Trying to create a cart for shopping app however each element when trying to add them to an array is added to individual arrays?

Viewed 84

I am working on a project to make a pizza app, however I've been stuck trying to get the add to cart function to work. I've got a file for managing adding items that are meant to be in the cart

import Foundation

class CartManager: ObservableObject {
    @Published private(set) var products: [Items] = []
    @Published private(set) var total: Int = 0
    
    func addToCart(product: Items) {
        products.append(product)
        total += product.price
    }
    
    func removeFromCart(product: Items) {
        products = products.filter {$0.id != product.id }
        total -= product.price
    }
}

And I've liked that to some code:

struct OptionCellStarter: View {

    @State var showingPopup: Bool = false
    @State var itemCounter: Int = 1
                
    @EnvironmentObject var cartManager: CartManager

    let optionStarter: Items
    
    var body: some View {
            Button(action: {
                showingPopup = true
            }, label: {
                VStack {
                    Image(optionStarter.imageName)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 150, height: 85)
                        .cornerRadius(10)
                    Text(optionStarter.title)
                    Text(String(optionStarter.price))
                }
            })
            .popover(isPresented: $showingPopup, arrowEdge: .bottom) {
                VStack {
                    Spacer()
                    Image(optionStarter.imageName)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 350, height: 200)
                        .padding(.bottom, 75)
                        .padding(.top, 100)
                    Text(optionStarter.title)
                        .font(.title2)
                    Spacer()
                    Text("Notes")
                        .font(.title2)
                        .padding(.trailing, 300)
                    TextField("Anything you'd like us to know...", text: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant("")/*@END_MENU_TOKEN@*/)
                        .padding()
                    Spacer()
                    HStack {
                        Button(action: {
                            if itemCounter > 1 {
                                itemCounter -= 1
                            } else {
                                print("Negative")
                            }
                        }, label: {
                            ZStack {
                                Circle()
                                    .fill(Color.gray)
                                    .frame(width: 75, height: 75)
                                Image(systemName: "minus")
                                    .font(.system(size: 16, weight: .heavy))
                                    .foregroundColor(.white)
                            }
                        })
                        .padding()
                        
                            Text(String(itemCounter))
                                .padding()
                        
                        Button(action: {
                           itemCounter += 1
                        }, label: {
                            ZStack {
                                Circle()
                                    .fill(.gray)
                                    .frame(width: 75, height: 75)
                                Image(systemName: "plus")
                                    .font(.system(size: 16, weight: .heavy))
                                    .foregroundColor(.white)
                                /*Text("+")
                                    .foregroundColor(.white)
                                    .font(.title3)
                            */
                            }
                        })
                        .padding()
                    }
                    Spacer()
                    Button(action: {
                        cartManager.addToCart(product: optionStarter)
                    }, label: {
                        Text("Add to Cart")
                            .font(.headline)
                            .foregroundColor(.white)
                            .padding()
                            .frame(width: 350, height: 75)
                            .background(Color.gray)
                            .cornerRadius(35.0)
                    })
                }
            }
    }
}

However, whenever I press the add to cart button it seems to add individual items to their own individual arrays not all to the same one, this baffles me.

Below, I'll attach a few more parts of the code to help anyone who wants to help. This is my first time making a project in swift, and I would really appreciate the help, I have no clue what's causing this.

Cart Page:

import SwiftUI

struct Cart: View {
    @EnvironmentObject var cartManager: CartManager
    
    
    var body: some View {
        ScrollView {
            if cartManager.products.count > 0 {
                ForEach(cartManager.products, id: \.id) {
                    product in
                    ItemsForCart(product: product)
                }
                

                HStack {
                    Text("Your Total is")
                    Spacer()
                    Text("$"+String(cartManager.total)+".00")
                        .bold()
                }
                .padding()
            } else {
                Text("Your Cart Is Empty")
            }
            
        }
    }
}


struct ItemsForCart: View {
    @EnvironmentObject var cartManager: CartManager
    var product: Items
    
    var body: some View {
        HStack(spacing: 20) {
            Image(product.imageName)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 50)
                .cornerRadius(10)
            
            VStack(alignment: .leading, spacing: 10) {
                Text(product.title)
                    .bold()
                
                Text("$" + String(product.price))
            }
            
            Spacer()
            
            Image(systemName: "trash")
                .foregroundColor(.red)
                .onTapGesture {
                    cartManager.removeFromCart(product: product)
                }
        }
        .padding(.horizontal)
        .frame(maxWidth: .infinity, alignment: .leading)
    }
}


struct Cart_Previews: PreviewProvider {
    static var previews: some View {
        Cart()
            .environmentObject(CartManager())
    }
}

Items Page:

import Foundation

struct Items: Identifiable {
    let id = UUID()
    let imageName: String
    let title: String
    let price: Int
}

var AllProducts = [Items(
    imageName: "placeholder",
    title: "Item Name",
    price: 30)] // Currently... to add more

This is also my firs time posting here, so if I've done something wrong apologies.

1 Answers

In your class CartManager replace the func addToCart() with this:

//before you added only a single item to "products" even you selected multiple items
func addToCart(pros: [Items]) {
    pros.forEach{sub in
        products.append(sub)
        total += sub.price
    }
    //for testing. can be removed.
    print(products)
    print(products.count)
    print(total)
}

In your Button Add to Cart replace your button action with this:

var arrs = [Items]()
for _ in 1...itemCounter {
    arrs.append(optionStarter)
}
cartManager.addToCart(pros: arrs)

Finally, in your struct Items, replace AllProducts with this:

var AllProducts = [Items]()

I have tested your code after this modification, it worked fine. Also, I'm glad your provided code worked with just copy/paste.

Related