Reputation: 179
I'm trying to push items to an array but I want that if there's a similar item in an array, to just update the count to 1 and not add the item another time on the array. I've tried plenty of things such as the include()
function but it is not working as expected, because when I put item.includes(product)
as I'm mapping through each product, whenever I add an item, the count gets updated for each product...
import React, {useState, useContext} from 'react'
import data from './data.js'
import useCountsContext from './context/useCountsContext.js'
var uniqid = require('uniqid');
function Shop({ data }) {
const {count, setCount} = useContext(useCountsContext)
const {item, setItem} = useContext(useCountsContext)
const addCart = (productsId) => {
setCount(count + 1)
data.forEach((product) => {
if (item.includes(product)) {
product.count += 1
} else if (product.id === productsId) {
setItem(item.concat(product))
}
})
}
console.log(item)
return (
<div>
<h1>Shop</h1>
<div className="div___shop">
{data.map(({id, img, button}) => (
<>
<img className="img___shop" key={id} src={img}></img>
<div key={id}>
<button onClick={() => addCart(id)}>{button}</button>
</div>
</>
))}
</div>
</div>
)
}
export default Shop
my data file:
import diCaprio from './img/diCaprio.jpg'
import steveJobs from './img/steveJobs.jpg'
import lips from './img/lips.jpg'
import buda from './img/buda.jpg'
import spaceDog from './img/spaceDog.jpg'
import astroNube from './img/astroNube.jpg'
import banksy from './img/Banksy.jpg'
import banksyDJ from './img/banksyDJ.jpg'
var uniqid = require('uniqid');
const data = [{
id: uniqid(),
title: "Steve Jobs",
img: steveJobs,
homeImg: steveJobs,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img: diCaprio,
homeImg: diCaprio,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img: lips,
homeImg: lips,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img: buda,
homeImg: buda,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img: spaceDog,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img:astroNube,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img: banksy,
button: "add to cart",
count: 0
},
{
id: uniqid(),
img:banksyDJ,
button: "add to cart",
count: 0
}
]
export default data;
Upvotes: 1
Views: 61
Reputation: 10463
includes
will not work with objects. try find
or findIndex
instead.
Also I think your check is wrong. You need to check if items
has the selected productId
and if yes, then update its count.
const addCart = (productsId) => {
setCount(count + 1)
data.forEach((product) => {
let index = items.findIndex(itm => itm.id === product.id && productId === product.id)
if (index >= 0) {
let newProduct = { ...items[index] }
newProduct.count += 1
setItem( [...item, [index]: newProduct ])
} else {
setItem(item.concat(product))
}
})
}
Upvotes: 2
Reputation: 4632
Since product is an object, includes
will not work as it only do "shallow" comparison like if you have a simple array (i.e ['a', 'b', 'c'].includes('c');
In your case you need to "find" the product by id to know if it exist.
const addCart = (productsId) => {
setCount(count + 1)
data.forEach((product) => {
const exist = item.find(i => i.id === product.id); // add this one
if (exist) {
product.count += 1
} else if (product.id === productsId) {
setItem(item.concat(product))
}
})
}
You can learn more about array.find here.
Upvotes: 0