NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

@ObservedObject not retrieving the changes

Forums > SwiftUI

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)
            }
        }
    }

   

@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

   

@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()

   

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.

   

Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

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

Reply to this topic…

You need to create an account or log in to reply.

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.