I have shopping cart app in swiftUI . Currently when I click the add to cart button that time , it is able to add the product record into view . But here is the problem . When I click the button twice that time same product record get again , to be more straight forward having duplicate record and seconds problem is , I am expecting to update the quantities of the product as well but I'm not sure how to do it Please suggest me to do it batter way.
Here is my code for List view ..
import SwiftUI
struct ProductListView: View {
var body: some View {
NavigationStack {
VStack {
if viewModel.productLists.count > 0 && !viewModel.refreshing {
List(viewModel.productList, id: \.self) { product in
ProductListViewCell(productData: product)
} .listStyle(.grouped)
}
}
}
.navigationTitle(Text("Product List"))
}
}
}
Here is the code for cell..
struct ProductListViewCell: View {
let productData: Product
@EnvironmentObject var order: Order
var body: some View {
HStack {
if let url = URL(string: productData.thumbnail) {
ProductAsyncImageView(url: url)
.frame(width: 150, height: 150)
.mask(RoundedRectangle(cornerRadius: 16))
}
VStack(alignment: .leading,spacing: 5) {
Text("Name: " + (productData.title))
.frame(maxWidth: .infinity, alignment: .leading)
.font(.headline)
Text("Description: " + (productData.description))
.frame(maxWidth: .infinity, alignment: .leading)
.multilineTextAlignment(.leading)
Text("Price: £" + String(productData.price))
.frame(maxWidth: .infinity, alignment: .leading)
.font(.subheadline)
Button {
order.add(item: productData)
} label: {
HStack {
Image(systemName: "cart.badge.plus")
Text("Add to Cart")
.fontWeight(.semibold)
}
.foregroundColor(.white)
.frame(width: 150 , height: 40)
}
.background(Color(.systemBlue))
.cornerRadius(10)
}
}
}
}
Here is my order class ..
import SwiftUI
class Order: ObservableObject {
@Published var product = [Product]()
func add(item: Product) {
product.append(item)
}
func remove(item: Product) {
if let index = product.firstIndex(of: item) {
product.remove(at: index)
}
}
}
Here is the code for order view..
struct OrderView: View {
@EnvironmentObject var order: Order
var body: some View {
NavigationStack {
List {
Section {
ForEach(order.product) { item in
HStack(spacing: 20) {
if let url = URL(string: item.thumbnail) {
ProductAsyncImageView(url: url)
.frame(width: 90, height: 90)
.padding(.bottom, -10)
.clipShape(Circle())
}
VStack(alignment: .leading) {
Text("Name: \(item.title)")
Text("Price :£\(item.price)")
Button("Show details") {
}.foregroundColor(.gray)
}
HStack {
Image(systemName: "multiply")
Text("1")
}
}
}
}
Section {
NavigationLink("Place Order") {
}
}
}
.navigationTitle("Order")
}
}
}
Here is the screenshot for product list view ..
Here is the screenshot having duplicate record when I click the add to button three time but I want only single record with Quantity 3.
In Product
class you should have a quantity
variable.
In Order.add(item:)
you should check if Product
exists in products
array, and increase its quantity
, as the following:
class Order: ObservableObject {
@Published var products = [Product]()
func add(item: Product) {
var exists = false
products.forEach { product in
if product.id == item.id {
exists = true
product.quantity += 1
}
}
if !exists {
product.append(item)
}
}
//The rest of your code...
}
quantity
in OrderView
, as the following:...
HStack {
Image(systemName: "multiply")
Text(item.quantity)
}
...
Fixed your typo in
Order
class:product:[Product]
->products:[Product]