Reputation: 99
I have a dynamic list of items a user adds. I want to avoid duplicating when a user adds an item already present in the list. My list looks like
itemList = [ {itemId:1, name:"x", quantity:5}, {itemId:4, name:"y", quantity:2}]
so now if a user adds item x with quantity 2 i want the object with item x to update the quantity to 7 rather than adding a whole new object. I am using find() method to get the item already present and storing it to a variable, itemObj is the item the user recently added.
let alrItem = state.itemList.find(
(e) => e.itemId === itemObj.itemId
);
let newItem = alrItem;
newItem.quantity += itemObj.quantity;
How do I merge this newItem to the itemList so that it just updates the quantity of that specific item?
Upvotes: 4
Views: 2782
Reputation: 29282
What you are doing is finding the object in the itemList
array and then mutating the state directly. State should not be mutated directly.
Instead of using .find()
method, use the .map()
method to iterate over the array and update the quantity of the item that matches with the id of the new item.
let updatedItemList = state.itemList.map((item) => {
if (item.itemId === itemObj.itemId) {
return { ...item, quantity: item.quantity + itemObj.quantity };
}
return item;
});
// update the state
setItemList(updatedItemList);
Note that above code will not do anything if the item isn't already present in the itemList
. Ideally, you should also handle the case where the new item isn't already present in the itemList
. In this case, you should just add the new item in the itemList
.
To handle this case, all you need is a extra variable that can be used to know whether the if
condition inside the .map()
method evaluated to true or not.
let exists = false;
let updatedItemList = state.itemList.map((item) => {
if (item.itemId === itemObj.itemId) {
exists = true;
return { ...item, quantity: item.quantity + itemObj.quantity };
}
return item;
});
// if the item isn't present in the list, add it in the "updatedItemList"
if (!exists) {
updatedItemList.push(itemObj);
}
// update the state
setItemList(updatedItemList);
Upvotes: 5
Reputation: 379
let itemList = [ {itemId:1, name:"x", quantity:5}, {itemId:4, name:"y", quantity:2}]
let itemObj = {itemId:1, name:"x", quantity:2}
const target = itemList.find(element =>
element.itemId === itemObj.itemId
);
if (target) {
target.quantity = target.quantity + itemObj.quantity;
} else {
itemList.push(itemObj);
}
console.log('itemList: ' + JSON.stringify(itemList));
OUTPUT:
itemList: [{"itemId":1,"name":"x","quantity":7},{"itemId":4,"name":"y","quantity":2}]
Upvotes: 0