Antonio Labra
Antonio Labra

Reputation: 2000

Left side of mutating operator isn't mutable: 'product' is a 'let' constant SwiftUI

Today I have a problem on SwiftUI in a ForEach.

I have a several list of products from different stores, the thing is I need to modify Stock when I press one of the buttons to increase or decrease it. but when I really try to make this I have the following error:

Left side of mutating operator isn't mutable: 'product' is a 'let' constant SwiftUI

I don't know how to make it works and I'm here to hear some suggestions

   @State var shoppingCartList : [Product]

            ForEach(productsByStore(storeId: store.id), id: \.self){product in
                                  
                                VStack(alignment: .leading,  spacing: 0){
                                
                                    HStack{
                                            
                                            Group{
                                                HStack{
                                                    HStack{
                                                        Button(action: {
                                                            if (product.quantity > 1){                                                          // error here:     product.quantity -= 1
                                                            }
                                                        }){
                                                            Text("—")
                                                                .multilineTextAlignment(.center)
                                                        }
                                                        .padding([.leading], 5)
                                                        
                                                        Text(String(product.quantity))
                                                                                                              
                                                        Button(action: {
                                                            if product.quantity < product.stock!{
                                                             // error here: product.quantity += 1
                                                            }
                                                            
                                                        }){
                                                            Text("+")
                                                                .multilineTextAlignment(.center)
                                                        }
                                                        
                                                    }
                                                    
                                                
                                                    Spacer()
                                                    
                                                    Text("available: " + String(describing: product.stock!))
                                                        
                                                     
                                                    
                                                }
                                            }
                                           
                                        }
                                    }
                                    
                                  Divider()
                                }
                                Spacer()
                            }


func productsByStore(storeId: Int) ->[Product] {
        return shoppingCartList.filter{$0.storeId == storeId}
    }

PS. productsByStore() returns a list of products according to the store PS2. product.stock is the number of available items on stock and product.quantity is the number of items that user can select.

ex: Palm One -> Quantity = 4. Stock = 10

I could add or remove the number of palm ones using buttons (+ and -)

PS3. Product Struct

    struct Product: Hashable, Codable{
    var name: String
    var quantity: Int
    var stock: Int?
    var storeId: Int
    
    init(from decoder: Decoder) throws{
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
        quantity = try container.decodeIfPresent(Int.self, forKey: .quantity) ?? 0
        stock = try container.decodeIfPresent(Int?.self, forKey: .stock) ?? 0

storeId = try container.decodeIfPresent(Int.self, forKey: .storeId) ?? 0
        }
    
    private enum CodingKeys: String, CodingKey{
        case name = "Nombre"
        case quantity = "Cantidad"
        case stock = "Stock"
        case storeId = "IdStore"
    }
        
    init(name: String, quantity: Int, stock: Int?, storeId: Int ){
        
        self.name = name
        self.quantity = quantity
        self.stock = stock
        self.storeId = storeId
    }
}

Upvotes: 0

Views: 136

Answers (1)

Antonio Labra
Antonio Labra

Reputation: 2000

I solved like this:

@State var selectedStock: Int = 0


    Button(action: {
        self.selectedStock = product.quantity
        if self.selectedStock > 1 {
            selectedStock -= 1
            if let listIndex = shoppingCartList.firstIndex(where: {
                $0 == currentProduct
            }) {
                var newProduct = product
                newProduct.quantity = selectedStock
                shoppingCartList[listIndex] = newProduct
    
            }
        }
    }) {
        Text("—")
    }


      Button(action: {
        self.selectedStock = product.quantity
        if self.selectedStock < product.stock!{
            selectedStock += 1

            if let listIndex = shoppingCartList.firstIndex(where: {
                $0 == currentProduct
            }) {
                var newProduct = product
                newProduct.quantity = selectedStock
                shoppingCartList[listIndex] = newProduct
            }

        }


    }) {
        Text("+")
         
    }

Upvotes: 1

Related Questions