skip to Main Content

I want to add new data to a list in my project
but I can’t do it

I have a ContentView.swift view for showing products list
and in another view (ShopView) I want to add data to products array
My products array and my addProduct() function
in the Products.swift file

Please help me
Thanks

ContentView.swift

struct ContentView: View {
    @ObservedObject var cart = Products()
    
    var body: some View {
        NavigationView{
            List {
                ForEach(cart.products) { product in
                    Text("(product.name) (product.price)$")
                }
            }
            .navigationBarItems(
                trailing: NavigationLink(destination: Shop()) {
                    Text("Go Shop")
                })
            .navigationBarTitle("Cart")
        }
    }
}

Product.swift

struct Product: Identifiable {
    var id = UUID()
    var name: String
    var price: Int
}

Shop.swift

struct Shop: View {
    @ObservedObject var cart = Products()
    
    var body: some View {
        VStack{
            Button("Add Product To Cart") {
                cart.addProduct(product: Product(name: "Name", price: 399))
            }
        }
    }
}

Products.swift

class Products: ObservableObject {
    @Published var products = [Product]()
    
    func addProduct(product: Product) {
        products.append(product)
        print("Product Added")
    }
}

2

Answers


  1. Right now, you’re creating two different instances of Products. If you want the data to be shared, you have to use the same instance.

    struct ContentView: View {
        @ObservedObject var cart = Products()
        
        var body: some View {
            NavigationView{
                List {
                    ForEach(cart.products) { product in
                        Text("(product.name) (product.price)$")
                    }
                }
                .navigationBarItems(
                    trailing: NavigationLink(destination: Shop(cart: cart)) {  //<-- HERE
                        Text("Go Shop")
                    })
                .navigationBarTitle("Cart")
            }
        }
    }
    
    
    struct Shop: View {
        @ObservedObject var cart : Products //<-- HERE
        
        var body: some View {
            VStack{
                Button("Add Product To Cart") {
                    cart.addProduct(product: Product(name: "Name", price: 399))
                }
            }
        }
    }
    

    Another way to achieve this type of functionality is by using an environment object. Additional reading on that approach: https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views

    Login or Signup to reply.
  2. I think you will find the simplest implementation will be to define your model as:

    class Products: ObservableObject {
        //Implement a shared resource here
        public static let shared = Products()
    
        // I would also make the published var name something different then the class name.
        // Otherwise you will be calling a lot of products.products.
        // Or you could change the name of the class to "Cart"
        @Published var products: [Product] = []
        
        func addProduct(product: Product) {
            products.append(product)
            print("Product Added")
        }
    }
    

    Use it in your structs with:
    @ObservedObject var cart = Products.shared

    This will give you one common shared Products class. You don’t have to worry about passing is around between views.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search