I have simple codeable json. I am using for each loop for iteration, here I comparing the product based on id. If the id exists, then it should increase the quantity otherwise add the item and I am using this function in view as well. But I am getting following error. Left side of mutating operator isn’t mutable; ‘quantity’ is a ‘let’ constant. I have tried to use mutating key word before the function and also change the struct let to var but it did not help.
Here is my codeable json.
import Foundation
// MARK: - Welcome
struct ProductData: Codable, Hashable {
let carts: [Cart]
}
// MARK: - Cart
struct Cart: Codable, Hashable {
let id: Int
let products: [Product]
}
// MARK: - Product
struct Product: Codable, Hashable, Identifiable {
let id: Int
let title: String
let price, quantity, total: Int
let discountPercentage: Double
let discountedPrice: Int
let thumbnail: String
}
Here is my function.
class Order: ObservableObject {
@Published var product = [Product]()
@Published private(set) var productTotal: Int = 0
func add(item: Product) {
var exists = false
product.forEach { product in
if product.id == item.id {
exists = true
product.quantity += 1 // error on this line
}
}
if !exists {
product.append(item)
}
}
}
Here is the screenshot of the error.
>Solution :
First of all please name product in plural form products.
@Published var products = [Product]()
There are two problems:
-
You have to declare
quantityinProductas variablevar quantity: Int -
Index variables/elements in loops are immutable. In fact they are immutable for a good reason: Due to value semantics the index element is a copy of the array item which won’t modify the original item in the array.
But you don’t need a loop at all. Try to get the index of the item in the array. If the item exists increase quantity otherwise append the item. products[index] modifies the array in place
func add(item: Product) {
if let index = products.firstIndex(where: {$0.id == item.id }) {
products[index].quantity += 1
} else {
products.append(item)
}
}
