godtrianglefd
godtrianglefd

Reputation: 179

How can you check if there is an existing value in the array and not add it another time if so?

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

Answers (2)

Apostolos
Apostolos

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

I am L
I am L

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

Related Questions