Home > Net >  How can I do so that once a certain product is added to the cart, if that product has already been a
How can I do so that once a certain product is added to the cart, if that product has already been a

Time:04-16

[ I need to avoid the duplication of an object that has already been added to the cart, so that once I add it again, I only add the quantity property of the previous object, which would be the same ]

[CartContext.js]

import React, { createContext, useState } from "react";

export const CarritoContext = createContext();

export default function CartContext({ children }) {
  const [addToCarrito, setAddToCarrito] = useState([]);

[This is the function that I cannot modify so that it complies with a certain rule of not adding duplicates of an object that has already been added to the cart, only increasing its quantity of the already added object]

  function addItem(item, quantity) {
    setAddToCarrito(
      addToCarrito.filter((elemento, pos) => {
        if (elemento.item.id === item.id) {
          addToCarrito[pos].quantity  = quantity;
          return false;
        }
        return true;
      })
    );

    if (quantity === 0) {
      setAddToCarrito([...addToCarrito]);
    } else {
      setAddToCarrito([...addToCarrito, { item, quantity }]);
    }
  }

  function clear() {
    setAddToCarrito([]);
  }

  function removeItem(itemId) {
    const newItems = addToCarrito.filter((item) => item.item.id !== itemId);
    setAddToCarrito(newItems);
  }

  console.log(addToCarrito);

  return (
    <>
      <CarritoContext.Provider
        value={{ addToCarrito, setAddToCarrito, clear, addItem, removeItem }}
      >
        {children}
      </CarritoContext.Provider>
    </>
  );
}

[ItemAside.js]

import React, { useState, useContext } from "react";
import { Link } from "react-router-dom";
import ItemCount from "../ItemCount/ItemCount";
import { CarritoContext } from "../../context/CartContext";

const ItemAside = ({ jackets }) => {
  const [quantityCarro, setQuantityCarro] = useState(0);
  const [branded] = useState(jackets.brand);

  let { addToCarrito } = useContext(CarritoContext);
  let { setAddToCarrito } = useContext(CarritoContext);
  let { clear } = useContext(CarritoContext);
  let { addItem } = useContext(CarritoContext);
  let { removeItem } = useContext(CarritoContext);

  const onAdd = (cantidadCarro) => {
    setQuantityCarro(cantidadCarro);
    setAddToCarrito([
      ...addToCarrito,
      { item: jackets, quantity: cantidadCarro }
    ]);
    addItem(jackets, cantidadCarro);
  };

  return (
    <div className="container-vertical">
      <aside style={{ width: "100%" }}>
        <div className="container-cuadrado">
          <div>
            <h3>${jackets.price}</h3>
          </div>
          <div>
            <p>and FREE Returns</p>
          </div>
          <div>
            <p>
              Delivery for <strong>$39.99</strong>
            </p>
            <p>
              between <strong>17 - 30 April</strong>
            </p>
          </div>
          <div>
            <small>
              <span className="ubicacion"></span> Deliver to Argentina
            </small>
          </div>

          <div>
            {quantityCarro ? (
              <>
                <Link to="/cart">
                  <button className="close zbutton">Buy now</button>
                </Link>
                <p onClick={clear}>Limpiar carro </p>
                <br />
                <br />
                <p onClick={() => removeItem(jackets.id)}>
                  {`Quitar ${jackets.name} de el carro`}
                </p>
              </>
            ) : (
              <ItemCount
                stock={jackets.stock}
                branded={branded}
                initial={0}
                onAdd={onAdd}
              />
            )}
          </div>

          <div>
            <div className="celwidget">
              <div className="a-section a-spacing-small a-text-left celwidget">
                <span className="a-declarative">
                  <span className="aok-align-center">
                    <img
                      alt=""
                      src="https://images-na.ssl-images-amazon.com/images/G/30/x-locale/checkout/truespc/secured-ssl._CB485936936_.png"
                      height="15px"
                    />
                  </span>
                  <span className="a-letter-space"></span>
                  <span
                    className="dataspan"
                    style={{
                      cursor: "pointer",
                      color: "#0099C0",
                    }}
                    data-hover="We work hard to protect your security and privacy. Our payment security system encrypts your information during transmission. We don’t share your credit card details with third-party sellers, and we don’t sell your information to others."
                  >
                    Secure transaction
                  </span>
                </span>
              </div>
            </div>
          </div>
          <div className="info-shipping">
            <div>
              <p>Shipping from</p>
              <p>Sold by</p>
            </div>
            <div>
              <p>Carvel</p>
              <p>Carvel</p>
            </div>
          </div>
          <div className="gift-container">
            <label className="control control--checkbox">
              <input type="checkbox" className="checkgift" />
              <small className="small-gift">
                 Add a gift ticket to facilitate returns
              </small>
            </label>
          </div>
        </div>
      </aside>
    </div>
  );
};

export default ItemAside;

CodePudding user response:

If I understand correctly, you have an array of products that looks like this:

[{
  item: {
    id: 'a',
  }
},
{
  item: {
    id: 'b',
  }
}

This is based on reading this line of code: if (elemento.item.id === item.id) {

If this is correct, I think the following code should work for you:

function addItem(item, quantity) {
  // This is one way to check if the product is already in the cart
  const existingItem = addToCarrito.find(el => el.item.id === item.id);
  if (existingItem) {
    // If it's in the cart already, map through the items and update
    // the quantity of the item matching the id
    setAddToCarrito(addToCarrito.map((el) => {
      if (el.item.id === item.id) {
        return {
          item: {
            ...el.item,
            quantity: el.item.quantity   quantity,
          },
        };
      }
      return el;
    }))
  } else {
    // else, return existing array and add the new item at the end
    setAddToCarrito([...addToCarrito, { item, quantity }]);
  }
}

CodePudding user response:

You can use findIndex.

const foundProdIndex = await products.findIndex((product) => product.item.id === item.id)
if (foundProdIndex === -1) {
  setProducts([
    ...products,
    { item, quantity },
  ])
} else {
  const newProducts = [...products]
  newProducts[foundProdIndex].quantity  = quantity
  setProducts(newProducts)
}

  • Related