UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

@ObservedObject not retrieving the changes

Forums > SwiftUI

@Aizen  

Hi all,

Based on the expense project, i tried to apply the what i learned on an app. However i am facing an issue that i am not able to find a solution. I have two sections: the first one contains ingredients and the second section which is empty should have all ingredients choosed from the first section.

I have created a class, which i add items that needs to added to the second section.

I am able to add items, however when i check the @ObservedObject var ingredientAdded = AddedIngredients() , it's empty. I am wondering what am i doing wrong in order to get it right and see it on the ui.

Thanks

struct Ingredient: Codable, Identifiable {
    let id: String
    let price: String
    let ajoute: Bool
}

class AddedIngredients: ObservableObject {

    @Published var ingredients = [Ingredient]()
}
struct CreationView: View {

    let ingredients: [Ingredient] = Bundle.main.decode("Ingredients.json")

    var body: some View {

        ScrollView {
            VStack{

                VStack(alignment: .leading) {
                    Image("creation")
                        .resizable()
                        .scaledToFit()
                    Text("Slectionnez vos ingredients preferes").fontWeight(.light)

                    RoundedRectangle(cornerRadius: 1).foregroundColor(.secondary).frame(height:1)
                        .padding(.bottom)

                }
            }
        }

        List {
            SectionIngredientsSelected()
            SectionIngredientsSelection(ingredients: ingredients)

        }
    }

    struct SectionIngredientsSelected: View {
         @ObservedObject var ingredientAdded = AddedIngredients()
        var body: some View {
            Section(header: VStack {
                HStack{
                    Text("Vos ingredients")
                        .textCase(nil)
                        .font(.headline)
                        .fontWeight(.bold)
                        .foregroundColor(.black)

                    Button(action: {print(ingredientAdded.ingredients.count)}, label: {Text("Add")})
                }
            }
    ) {
                ForEach(ingredientAdded.ingredients){ingredient in
                    HStack{
                        HStack{
                            Image("mais")
                                .resizable()
                                .frame(width: 20, height: 20)
                            Text(ingredient.id)
                        }
                        Spacer()
                        HStack{
                            Text(ingredient.price )
                            Button(action: {
                            }){
                                Image(systemName: "xmark.circle")
                                    .foregroundColor(Color(#colorLiteral(red: 0, green: 0.3257463574, blue: 0, alpha: 1)))
                            }
                        }
                    }
                }
                .listRowBackground(Color.white)
                .listRowSeparator(.hidden)
            }
        }
    }

    struct SectionIngredientsSelection: View {
        let ingredients: [Ingredient]
        @StateObject var ajoute = AddedIngredients()
        var body: some View {
            Section(header: VStack {
                Text("Ajouter vos ingredients")
                    .textCase(nil)
                    .font(.headline)
                    .fontWeight(.bold)
                    .foregroundColor(.black)
            }
    ) {
                ForEach(ingredients){ingredient in
                    HStack{
                        HStack{
                            Image("mais")
                                .resizable()
                                .frame(width: 20, height: 20)
                            Text(ingredient.id)
                        }
                        Spacer()
                        HStack{
                            Text(ingredient.price )
                            Button(action: {
                                ajoute.ingredients.append(ingredient)
                                print(ajoute.ingredients.count)
                            }){
                                Image(systemName: "plus")
                                    .foregroundColor(Color(#colorLiteral(red: 0, green: 0.3257463574, blue: 0, alpha: 1)))
                            }
                        }
                    }
                }
                .listRowBackground(Color.white)
                .listRowSeparator(.hidden)
            }
        }
    }

1      

@Bnerd  

@ObservedObject var ingredientAdded = AddedIngredients()

The above initialises a new instance every time, thus if you don't have anything predefined it will be empty. You should pass around the @ObservedObject like this:

@ObservedObject var ingredientAdded: AddedIngredients

1      

@Aizen  

@Bern, Thanks for your response.

I have tried it but no result. I still see 0 elements in


ingredientAdded.ingredients

Quick question, the fact that uei this code below, shouldn't it work. My understanding is that class are reference type, so it should point to the same object unless i overrride it. Am i missing something ?

@ObservedObject var ingredientAdded = AddedIngredients()

1      

Here you have defined the ingredients array, but there's nothing in it for the ForEach loop to use.

struct SectionIngredientsSelection: View {
    let ingredients: [Ingredient]
    @StateObject var ajoute = AddedIngredients()
    var body: some View {
        Section(header: VStack {
            Text("Ajouter vos ingredients")
                .textCase(nil)
                .font(.headline)
                .fontWeight(.bold)
                .foregroundColor(.black)
        }
) {
            ForEach(ingredients){ingredient in
                HStack{

See if this helps

            ForEach(ajoute.ingredients) {ingredient in

Be careful that your id is unique, to avoid problems. Otherwise you coudl try this

            ForEach(ajoute.ingredients, id: \.self) {ingredient in

Also, as Bnerd has already stated, the ObservedObject should declared as

@ObservedObject var ingredientAdded: AddedIngredients

See here for an explanation.

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.