how to show only unique item when append for my Cart View SWIFTUI

Viewed 203

This are my code. Im Creating Cash Register IPAD

What is see: When I tap the item twice with the same item name it adds another row instead

What I expect: My expectation is it only adds one row of item and its quantity counter

Hope Someone can help me. I already research cannot find sample or any info to direct for what I want to achieved. Thanks all

Screenshot on iPad

import Foundation
import SwiftUI

class OrderViewModel: ObservableObject {

   @Published var orderItems = [Cart]()
   @State var count: Int = 1
   
   func AddToCart(item: item){
         orderItems.append(
            Cart(product_name: item.product_name, price:item.price, quantity: quantity )
        )
    }
}


  struct Cart: Identifiable{
    
   var id = UUID()
   var product_name: String
    var price: String
    var quantity: Int
}

This are my cartView the will print all @EnvironmentObject from class OrderViewModel

import SwiftUI

struct CartContainer: View {
    
    @EnvironmentObject var order: OrderViewModel
    var body: some View{
        ZStack{
             Color("lightGrayColor")
            .ignoresSafeArea()
            VStack(alignment: .leading) {
                VStack{
                    HStack{
                        Text("Item Name")
                            .font(Font.system(size: 16, weight: .light))
                            .frame(width:200)
                        Spacer()
                        Text("Qty.").font(Font.system(size: 16, weight: .light))
                            .padding(.leading, -78)
                        Spacer()
                        Text("Subtotal.").font(Font.system(size: 16, weight: .light))
                            .padding(.leading, -78)
                    }
                }
                .padding(.top, 10)
                ScrollView{
                    VStack(alignment: .leading){
                        ForEach(order.orderItems, id:\.id){ list in
                            HStack{
                                 Text(list.product_name)
                                         .font(Font.system(size: 16, weight: .light))
                                         .frame(width:200)
                                     Spacer()
                                 Text(list.price).font(Font.system(size: 16, weight: .light))
                                         .padding(.leading, -78)
                                     Spacer()
                                Text("\(list.quantity)").font(Font.system(size: 16, weight: .light))
                                         .padding(.leading, -78)
                           }
                            .padding(.top, 10)
                    }
                    }.padding()
                }.padding()
                Text("Grand Total :")
                    .font(Font.system(size: 30, weight: .bold))
                    .padding(.bottom, 30)
                    .padding(.leading, 40)
                Button(action: {
                }) {
                               Text("Charge")
                                .foregroundColor(.white)
                                .font(Font.system(size: 30, weight: .bold))
                                .frame(minWidth: 0, maxWidth: .infinity)
                                .padding(.top, 35)
                                .padding(.bottom, 35)
                                .background(Color("ButtonGreen"))
                }.padding(.bottom, -10)
                          
            }
        }
        .frame(width: 550)
    }
}


struct CartContainer_Previews: PreviewProvider {
    static var previews: some View {
        CartContainer().environmentObject(OrderViewModel())
  }
}

And this are the Product List which I pullout from API

import SwiftUI


struct ProductsListContainer: View {

    var body: some View{
        ZStack{
            Color(.white)
            VStack{
                ProductList()
            }
        }
        .frame(maxWidth: .infinity)
    }
}

struct ProductList: View{
   
    var body: some View{
        VStack {
            SearchItem()
            ItemListHeader()
            ShowItemList()
            .padding(5)
        }
        
    }
}

struct ItemListHeader: View {
    var body: some View {
        HStack{
            Text("Item Name")
                .font(Font.system(size: 20, weight: .heavy))
                .frame(width:300)
            Spacer()
            Text("Price").font(Font.system(size: 20, weight: .heavy))
                .padding(.leading, -78)
            Spacer()
            Text("Qty.").font(Font.system(size: 20, weight: .heavy))
                .padding(.leading, -78)
        }
        Divider()            
    }
}


struct ShowItemList: View {
    @StateObject  var itemVM = ProductViewListModel()
    @EnvironmentObject var order:  OrderViewModel

    var body: some View {
        ScrollView {
            ForEach(itemVM.item) { dataPoint in
                ZStack{
                HStack{
                    Text(dataPoint.product_name)
                        .font(.headline)
                        .frame(width:300)
                    Spacer()
                    Text(dataPoint.price)
                    Spacer()
                    Text("\(dataPoint.quantity)")
                }
                .padding()
                .padding(.leading, -20)
                .padding(.trailing, 20)
                .padding(.top, 5)
                .padding(.bottom, 5)
            }.onTapGesture {
                self.order.AddToCart(item: dataPoint.product)
            }
                Divider()
            }
          }
        .padding()
       }
   }
1 Answers

When you use "AddToCart(...)", you need to check if you have the item already. Try something similar to this:

class OrderViewModel: ObservableObject {
    @Published var orderItems = [Cart]()
    
    // note: comparing product_name, assuming product_name is unique here
    func AddToCart(item: Item) {
        if let ndx = orderItems.firstIndex(where: {$0.product_name == item.product_name}) {
            // already have this cart/item, do an update here
            orderItems[ndx].price = item.price
            orderItems[ndx].quantity = item.quantity
        } else {
            // add a new cart/item
            orderItems.append(Cart(product_name: item.product_name, price:item.price, quantity: item.quantity))
        }
    }
}

and probably call it like this:

.onTapGesture {
    self.order.AddToCart(item: dataPoint)
 }
Related