Daniel
Daniel

Reputation: 27

How to add items to a cart in React

I made an app with React which is displaying 9 products on the screen. I made a button to add them to a cart and I want to make the app functionally just for demo purpose. I used hooks and I don't know what I did wrong.Here are the errors that I'm receiving:

Uncaught TypeError: Cannot read properties of undefined (reading 'map')
    at Products (Products.js:8:1)
react-dom.development.js:18523 The above error occurred in the <Products> component:

    at Products (http://localhost:3000/main.f01d7322f0afd7419d5f.hot-update.js:30:5)
    at Routes (http://localhost:3000/static/js/bundle.js:40456:5)
    at Router (http://localhost:3000/static/js/bundle.js:40389:15)
    at BrowserRouter (http://localhost:3000/static/js/bundle.js:39198:5)
    at App (http://localhost:3000/static/js/bundle.js:44:84)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

Here is the full project: https://github.com/burNN11/Project

import productItems from './data/Data'

const Products = ({handleAddProduct, productItems}) => {
  console.log(productItems)
  return (
    <div className='produse'>
      {productItems.map((item)=> (
        <div className='produs' key={item.id}>
          <div>
            <img className='imagine-produs'
              src={item.image} 
              alt = {item.name}

Upvotes: 0

Views: 5969

Answers (1)

Sam McElligott
Sam McElligott

Reputation: 326

Edit

I cloned your project, applied my fix and got it to work. The offending code is in App.js, in the handleAddProduct() handler:

const handleAddProduct = product => {
    const ProductExist = cartItems.find(item => item.id === product.id);
    if (ProductExist) {
      setCartItems(
        cartItems.map(item =>
          item.id === product.id
            ? { ...ProductExist, quantity: ProductExist.quantity + 1 }
            : item
        )
      );
    } else {
      setCartItems([...cartItems, { 
        ...product, 
        quantity: ProductExist.quantity + 1  // <-- error is here
      }]);
    }
  };

In the else block, ProductExist is undefined, as the only way to get into the else block is for it to be undefined. But you try to use ProductExist.quantity + 1. It should be just 1, like this:

const handleAddProduct = product => {
    const ProductExist = cartItems.find(item => item.id === product.id);
    if (ProductExist) {
      setCartItems(
        cartItems.map(item =>
          item.id === product.id
            ? { ...ProductExist, quantity: ProductExist.quantity + 1 }
            : item
        )
      );
    } else {
      setCartItems([...cartItems, { 
        ...product, 
        quantity: 1  // <-- Change here
      }]);
    }
  };

With this change, the cart feature is working on my machine, on localhost. There is no UI update to show the new items in the cart, but I checked the console and the items are being added correctly, without errors.

Hope this helped.

Original answer

In components/Products.js, you define the <Products/> component as:

import productItems from './data/Data'

const Products = ({handleAddProduct, productItems}) => {
  console.log(productItems)
  ...

You override the productItems import by defining it as a prop. This is because of how JavaScript handles scope. The definition in the function parameters takes precedence.

You should change the lines above to remove the prop, like this:

import productItems from './data/Data'

const Products = ({handleAddProduct}) => {
  console.log(productItems)
  ...

You don't pass the productItems prop in App.js, hence the prop is undefined when you try to map over it.

Upvotes: 2

Related Questions