This error appears to me when I add something to the shopping cart . I've checked the code many times, but I still can't find the solution, I don't know how to make it work.
code in cartActions.js
import axios from 'axios'
import { CART_ADD_ITEM } from '../constants/cartConstants';
export const addToCart = (id, qty) => async (dispatch, getState) => {
const { data } = await axios.get(`/api/products/${id}`)
dispatch({
type: CART_ADD_ITEM,
payload: {
product: data._id,
name: data.name,
image: data.image,
price: data.price,
countInStock: data.countInStock,
qty
}
})
localStorage.setItem('cartItems', JSON.stringify(getState().cart.cartItems))
}
code in cardReducers.js I think the problem comes from here, but I don't know exactly where to change
import { CART_ADD_ITEM } from "../constants/cartConstants"
export const cartReducer = (state = { cartItems: [] }, action) => {
switch (action.type) {
case CART_ADD_ITEM:
const item = action.payload
const existItem = state.cartItems.find(x => x.product === item.product)
if(existItem){
return{
...state,
cartItems: state.cartItems.map(x =>
x.product === existItem.product ? item:x)
}
}else{
return{
...state,
cartItems:[...state.cartItems, item]
}
}
default:
return state;
}
}
code in CartScreen.js
import React, {useEffect} from 'react'
import { useParams, useLocation } from 'react-router-dom';
import { useDispatch, useSelector} from 'react-redux';
import { Row, Col, ListGroup, Image, Form, Button, Card } from 'react-bootstrap';
import { Message } from '../components/Message';
import { addToCart } from '../actions/cartActions';
function CartScreen() {
const {prodId} = useParams()
const location = useLocation()
const qty = location.search ? Number(location.search.split('=')[1]) : 1
const dispatch = useDispatch()
const cart = useSelector(state => state.cart)
const { cartItems } = cart
useEffect(() => {
if (prodId) {
dispatch(addToCart (prodId, qty))
}
}, [dispatch, prodId, qty])
return(
<div>
Cart
</div>
)
};
export default CartScreen
Here I have attached an image with the error
x is null so you can't access the product property on it. Just use optional chaining here or add an if check. This should fix the error:
const existItem = state.cartItems.find(x => x?.product === item.product)
But don't know why the item even is null, maybe you should figure that out first.
this is the modified code as you told me, but i have the same error. sorry to bother you but i really don t have anyone to ask .thank you very much for your help
cartReducer.js code
import { CART_ADD_ITEM } from "../constants/cartConstants"
export const cartReducer = (state = { cartItems: [] }, action) => {
switch (action.type) {
case CART_ADD_ITEM:
const item = action.payload
const existItem = state.cartItems.find(x => {
if(x == null){
return false;
}else{
return x.product === item.product;
}
})
if(existItem){
return{
...state,
cartItems: state.cartItems.map(x =>
x.product === existItem.product ? item:x)
}
}else{
return{
...state,
cartItems:[...state.cartItems, item]
}
}
default:
return state;
}
}
cartScreen.js code
import React, {useEffect} from 'react'
import { useParams, useLocation } from 'react-router-dom';
import { useDispatch, useSelector} from 'react-redux';
import { Row, Col, ListGroup, Image, Form, Button, Card } from 'react-bootstrap';
import { Message } from '../components/Message';
import { addToCart } from '../actions/cartActions';
function CartScreen() {
const {prodId} = useParams()
const location = useLocation()
const qty = location.search ? Number(location.search.split('=')[1]) : 1
const dispatch = useDispatch()
const cart = useSelector(state => state.cart)
const {cartItems} = cart
console.log('cartItems:', cartItems)
useEffect(() => {
if (prodId) {
dispatch(addToCart (prodId, qty))
}
}, [dispatch, prodId, qty])
return(
<div>
Cart
</div>
)
};
export default CartScreen
This appears when I access one of the products and click on the shopping cart to select the quantity
It's the same error just for the map method on line 24. So all you have to do is add another if statement to check wether x is null or undefined, just like above.
It should look like this:
return {
...state,
cartItems: state.cartItems.map(x => {
if (x != null) {
return x.product === existItem.product ? item : x
} else {
return x
}
})
}
or with optional chaining:
return{
...state,
cartItems: state.cartItems.map(x => x?.product === existItem.product ? item : x)
}
Im still wondering why your first item is null. Could it be that you initialized the store with this value?