So my im trying to create a cart using Context and Local storage. with add to cart already done and work. But when im trying to add item that already in cart i get this error. I use find() and map() to find and check id that already in cart or not, if it is add that item into cart and increase quantity. But when i do that, other item in cart will become underfined?
Here is image that work when i add to cart
Here is if i add item 2 (already exist in cart), item 1 will become underfined
this is my cartcontext.js:
import { createContext, useContext, useState, useEffect } from "react";
// import { Items } from "../../Data/AllDatas";
const CartContext = createContext();
export const CartProvider =({children})=>{
// const [cartItem, setCartItem] = useState([])
const [cartItem, setCartItem] = useState(() => {
const json = localStorage.getItem('cartItem');
return json ? JSON.parse(json) : [];
});
const [qty, setQty] = useState(1);
const [showCart, setShowCart] = useState(false);
const [totalQty, setTotalQty] = useState(0);
const [totalPrice, setTotalPrice] = useState();
const increaseQty = ()=>{
setQty(prevQty => prevQty+1)
}
const decreaseQty = () =>{
setQty((prevQty)=>{
if(prevQty - 1< 1)return 1
return prevQty-1
})
}
useEffect(() => {
const json = localStorage.getItem('cartItem');
const savedCart = JSON.parse(json);
if (savedCart) {
setCartItem(savedCart);
}
console.log("LocalStorage data:", savedCart);
}, []);
useEffect(() => {
const json = JSON.stringify(cartItem);
localStorage.setItem("cartItem", json);
}, [cartItem]);
// {id: 1, quantity :1}
const addToCart = (Item, quantity)=>{
setTotalPrice((prevTotalPrice)=>prevTotalPrice + prevTotalPrice*quantity)
setTotalQty((prevTotalQty)=> prevTotalQty + quantity)
const checkProduct = cartItem.find((product)=> product.id === Item.id)
if(checkProduct){
const updateCart = cartItem.map((product)=>{
if(product.id === Item.id)return{
...product,
quantity: product.quantity + quantity,
}
})
setCartItem(updateCart);
setQty(1);
}
else{
Item.quantity = quantity;
setCartItem([...cartItem, {...Item}])
}
}
const contextValue = {
showCart,
qty,
totalPrice,
increaseQty,
decreaseQty,
totalQty,
addToCart,
setShowCart,
setCartItem,
cartItem
}
return(
<CartContext.Provider value ={contextValue}>
{children}
</CartContext.Provider>
)
}
export const useCartProvider = () => useContext(CartContext)
``
this is product.js
import React, {useState, useEffect } from 'react'
import {Items} from '../../Data/AllDatas';
import { useParams } from 'react-router';
import './Product.css';
import {useCartProvider} from '../CartProvider/CartContext';
const Product = () => {
const {id} = useParams();
const Item = Items.filter((Item) => Item.id === parseInt(id));
const [image, setImage] = useState(Item[0].front)
const {qty, decreaseQty, increaseQty, addToCart} = useCartProvider()
const changeImage= (e) =>{
setImage(e.target.src)
}
return (
<div className='containerProduct'>
<div className='route'>
<p>Home/ </p>
<p>Ready To Wear/ </p>
<p> {Item[0].des}</p>
</div>
<div>
<div className='productDisplay'>
<div className='left'>
<div className='smallImg'>
<img src={Item[0].front}
onClick={changeImage}/>
<img src={Item[0].back}
onClick={changeImage}/>
</div>
<div className='bigImg'>
<img src={image} alt={image}/>
</div>
</div>
<div className='right'>
<p>{Item[0].des}</p>
<h4>{Item[0].price}</h4>
<div className='addItem'>
<h1>Quantity: </h1>
<button onClick={decreaseQty}>-</button>
<h1>{qty}</h1>
<button onClick={increaseQty}>+</button>
</div>
<div className='button'>
<button
onClick={() => addToCart(Item[0], qty)}
>
Add to cart
</button>
<button>Buy now</button>
</div>
</div>
</div>
</div>
<div className='des'>
<p>Detail: {Item[0].detail}</p>
</div>
</div>
)
}
export default Product;
Have you guys seen this before or any idea to solve this? this actually headache in past few hours.
The problem is with your map method in the addCart function.
The callback function in map() method is called for every element of Array and expects an element to return, but here you're returning nothing when the id of the item is mismatched, which is why the other values become undefined.
See this example for better understanding
const arr = [4, 1, 2, 9];
const mp = arr.map((x) => {
if (x === 1) {
return "Hello";
}
});
console.log(mp);
// Expected output: Array [undefined, "Hello", undefined, undefined]
Solution: Modify your map method in addCart function like this
const updateCart = cartItem.map(product => {
if(product.id === Item.id) return {
...product,
quantity: product.quantity + quantity,
}
return product;
})