1👍
That is because your if condition is not checking for what you think.
Array.prototype.includes
checks if a value is in the array but there are two cases:
- the value is a primary type (string, number, boolean, …). It compares by value.
- the value is an object. Then it compares by reference.
So here, you are checking if the reference of your item object is already included in the array. But it’s not, since it’s a new object.
Solution: check if there is an object with the same values, not reference.
You can use the some
method, and you have to write a condition that checks if two items are equals.
Here is an example if your items have an id:
if (state.checkoutCart.some(item => item.id === payload.item.id))
0👍
The problem is indeed inside ADD_ITEM_TO_CART
mutation.
As Kapcash has pointed out, two objects having the same properties and the same values are not the same.
In other words, .includes()
checks for identity, not equality. To better understand this, consider this example:
const a = { foo: 'bar' }
const b = [{ foo: 'bar' }]
const c = [a]
const d = [{ ...a }]
console.log(b.includes(a)) // false
console.log(c.includes(a)) // true
console.log(d.includes(a)) // false
To get past this, use Kapcash’s answer.
I’ll just mention the standard way of dealing with this problem is using unique identifiers on objects (e.g: uuids).
Once you fix the above, it’s still not going to work, because you’ll run into the following problem: inside the if
you’re attempting to alter state.checkoutCart
‘s quantity
. And an array does not have a quantity
property.
The proper logic to achieve the desired functionality is (assuming the unique identifier on checkoutCart
members is item._id
, from the pictures you posted):
ADD_ITEM_TO_CART(state, payload) {
// find the index of a cart element having same `item._id` value as the payload
const index = state.checkoutCart.findIndex(
(el) => el.item._id === payload.item._id
)
if (index > -1) {
// if the index is higher than `-1`, an element was found
// create a copy, update its quantity and then
// replace the original element with the copy
const copy = { ...state.checkoutChart[index] }
copy.quantity += payload.quantity
state.checkoutCart.splice(index, 1, copy)
} else {
// no element found, add payload to `checkoutCart`
state.checkoutCart.push(payload)
}
}
Side note: None of your item
s should contain a quantity
property. That’s the cart’s responsibility, not the item’s. By adding it to the item
you end up with two sources of truth which you’d need to keep in sync. You don’t want this type of problem.
- [Vuejs]-How to detect if user pressed back button with vue router?
- [Vuejs]-Fetched response data is not being stored in component's data property