After adding products to cart I am able to increase and decrease their quantities, but when the total quantity is decreased to zero, I want to remove it from the DOM. I tried the filter method in the "decreaseQuantity" function, but it is not working. I played around with the placement of the drawCart() function as well, but no luck.
Note: let cart = [] is a global variable that is being used in these functions.
Function to display cart items:
function drawCart() {
let cartList = document.querySelector('.cart');
// clear cart before drawing
let cartItems = '';
cart.forEach((element) => {
let itemTotal = element.price * element.quantity;
cartItems = `
<div data-productId='${element.productId}'>
<h3>${element.name}</h3>
<p>price: ${currencySymbol}${element.price}</p>
<p>quantity: ${element.quantity}</p>
<p>total: ${currencySymbol}${itemTotal}</p>
<button onclick="increaseQuantity(${element.productId})"> </button>
<button onclick="decreaseQuantity(${element.productId})">-</button>
<button onclick="removeProductFromCart(${element.productId})">remove</button>
</div>
`;
});
// use innerHTML so that cart products only drawn once
cart.length
? (cartList.innerHTML = cartItems)
: (cartList.innerHTML = 'Cart Empty');
}
Function to decrease quantity of items:
function decreaseQuantity(productId){
cart = cart.map((item) => {
let quantity = item.quantity;
//pick out the item that we want to decrease quantity of
if(item.productId === productId){
if(item.quantity>1){
quantity--;
console.log(quantity);
}else{
cart = cart.filter((item) => item.productId != productId );
//re-render cart
drawCart();
}
}
return {
...item,
quantity, //if old quantity gets changed from the map function, then it'll show up here
};
});
drawCart()
}
CodePudding user response:
When you run
cart = cart.filter((item) => item.productId != productId );
variable cart
is changed, yet the array still exists. Therefore, after the loop, cart
is again set to map
value.
A possible fix is using flatMap
and return []
when it needs to be removed:
function decreaseQuantity(productId){
cart = cart.flatMap((item) => {
let quantity = item.quantity;
//pick out the item that we want to decrease quantity of
if(item.productId === productId){
if(item.quantity>1){
quantity--;
console.log(quantity);
}else{
return [];
}
}
return {
...item,
quantity, //if old quantity gets changed from the map function, then it'll show up here
};
});
drawCart()
}
The flatMap() method returns a new array formed by applying a given callback function to each element of the array, and then flattening the result by one level.
flatMap can be used as a way to add and remove items (modify the number of items) during a map. In other words, it allows you to map many items to many items (by handling each input item separately), rather than always one-to-one. In this sense, it works like the opposite of filter. Return a 1-element array to keep the item, a multiple-element array to add items, or a 0-element array to remove the item.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
CodePudding user response:
You forgot to update quantity to 0 before returning, so that the item quantity is updated in the cart. Also, you need to move the cart.filter outside of the if(item.quantity>1).
function decreaseQuantity(productId){
cart = cart.map((item) => {
let quantity = item.quantity;
//pick out the item that we want to decrease quantity of
if(item.productId === productId){
if(item.quantity>1){
quantity--;
console.log(quantity);
}
}
if (item.productId === productId && item.quantity <= 1) {
cart = cart.filter((item) => item.productId != productId );
}
return {
...item,
quantity: quantity <= 0 ? 0 : quantity,
// update quantity to 0 if it's already 1 or less
};
});
drawCart();
}
CodePudding user response:
Instead of re-draw that entire cart when you decrease the cart i think you just need to delete that particular DOM if quantity == 0 that whould be better just give that div a unique id.