Click here to Skip to main content
15,885,842 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Recently I wanted to make a functionality where if the user has added a product to cart, then it will be stored in the Local Storage.

I tried to implement this in my Product.jsx file. And this is the code I used to make the product stored in Local Storage:
const saveLocalProducts = () => {
    localStorage.setItem("products", JSON.stringify(products));
  };
  const getLocalProducts = () => {
    if (localStorage.getItem("products") === null) {
      localStorage.setItem("products", JSON.stringify([]));
    } else {
      let productLocal = JSON.parse(localStorage.getItem("games"));
      setProducts(productLocal);
    }
  };
  useEffect(() => {
    getLocalProducts();
    saveLocalProducts();
  }, []);

Note: this is also after the addToCart() function where all the variables are.
Then I saved and this is what I got:

Error Image

Here's where the error says it's located:
return (
    <div className="products">
      <h1 className="big-text">Games</h1>

      {/* Cards */}
      <div className="products">
        <ul className="flex cards">
          {products.map((product, index) => (
            <li key={index}>
              <h2>{product.name}</h2>
              <div className="space3"></div>
              <img src={product.image} alt={product.name} />
              <div className="space"></div>
              <div className="buy-product">
                <button onClick={() => (window.location.href = product.link)}>
                  Buy
                </button>
              </div>
              <h4>${product.cost}</h4>
              <div className="cart-container">
                <div className="space2"></div>
                <div className="product-icon">
                  <a className="cart" onClick={() => addToCart(product)}>
                    <FaCartPlus />
                  </a>
                </div>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );

A possibly useful tip: when you clear storage and refresh the tab, it shows the games page, and everything works fine; but when you refresh the tab again, it'll show an error.

Help is very much appreciated!

EDIT: Also, this is my full updated file which is on GitHub:

import React, { useState, useEffect } from "react";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { FaCartPlus } from "react-icons/fa";

toast.configure();

function Products({ setCart, cart }) {
  const [products, setProducts] = useState([
    {
      name: "Cyber Punk 2077",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1rft.jpg",
      link: "https://www.cyberpunk.net/us/en/pre-order",
    },
    {
      name: "Fall Guys",
      cost: 28.95,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2fq7.jpg",
      link:
        "https://store.steampowered.com/app/1097150/Fall_Guys_Ultimate_Knockout/",
    },
    {
      name: "Among Us",
      cost: 7.5,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1uaf.jpg",
      link: "https://store.steampowered.com/app/945360/Among_Us/",
    },
    {
      name: "A Monster's Expedition",
      cost: 28.95,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2eop.jpg",
      link: "https://store.steampowered.com/app/1052990/A_Monsters_Expedition/",
    },
    {
      name: "Halo Infinite",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2dto.jpg",
      link: "https://store.steampowered.com/app/1240440/Halo_Infinite/",
    },
    {
      name: "Rocket League",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2hnd.jpg",
      link:
        "https://store.steampowered.com/app/252950/Rocket_League/?curator_clanid=11855704",
    },
    {
      name: "The Falconeer",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2e3l.jpg",
      link: "https://store.steampowered.com/app/1135260/The_Falconeer/",
    },
    {
      name: "Genshin Impact",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1ltz.jpg",
      link: "https://genshin.mihoyo.com/en",
    },
  ]);
  const addToCart = (product) => {
    let newCart = [...cart];
    let itemInCart = newCart.find((item) => product.name === item.name);

    if (itemInCart) {
      toast.error(`${product.name} is already in cart`, {
        autoClose: 1300,
      });
    } else {
      itemInCart = {
        ...product,
        quantity: 1,
      };

      toast.success(`${product.name} has been added to cart`, {
        autoClose: 1200,
      });

      newCart.push(itemInCart);
    }

    setCart(newCart);
  };
  const item = useState([]);

  const saveLocalProducts = () => {
    localStorage.setItem("games", JSON.stringify(item));
  };
  const getLocalProducts = () => {
    if (localStorage.getItem("games") === null) {
      localStorage.setItem("games", JSON.stringify([]));
    } else {
      let productLocal = JSON.parse(localStorage.getItem("games"));
      setProducts(productLocal);
    }
  };
  useEffect(() => {
    getLocalProducts();
    saveLocalProducts();
  }, []);

  if (item) {
    return (
      <div className="products">
        <h1 className="big-text">Games</h1>

        {/* Cards */}
        <div className="products">
          <ul className="flex cards">
            {products.map((product, index) => (
              <li key={index}>
                <h2>{product.name}</h2>
                <div className="space3"></div>
                <img src={product.image} alt={product.name} />
                <div className="space"></div>
                <div className="buy-product">
                  <button onClick={() => (window.location.href = product.link)}>
                    Buy
                  </button>
                </div>
                <h4>${product.cost}</h4>
                <div className="cart-container">
                  <div className="space2"></div>
                  <div className="product-icon">
                    <a className="cart" onClick={() => addToCart(product)}>
                      <FaCartPlus />
                    </a>
                  </div>
                </div>
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }
}

export default Products;


What I have tried:

I've tried renaming the key name and searching it up with no solutions.

Though I did see a question that kind of relates, which is this question on Reddit...though it didn't help much, as you needed a default value, and since this is with products, I can't really have a default value, because it would have to mean a game is already in the cart, before you even clicked an add to cart button. If you know what I mean?
Posted
Updated 12-Nov-20 15:36pm
v7
Comments
Sandeep Mewara 12-Nov-20 1:19am    
Don't see map in your code above. Use Improve Question and update the part where you use map.
h311o 12-Nov-20 1:43am    
Oops, sorry! I thought I already put that in there...

1 solution

How have you defined products is still not clear. I can just guess that its initialized as null in your component and that is causing an error.

map works only on arrays. So, check products is defined array before doing map on it.
Try this and see:
HTML
if(products)
{
  products.map((product, index) => (
    <li key={index}>
      <h2>{product.name}</h2>
      <div className="space3"></div>
      <img src={product.image} alt={product.name} />
      <div className="space"></div>
      <div className="buy-product">
        <button onClick={() => (window.location.href = product.link)}>
          Buy
        </button>
      </div>
      <h4>${product.cost}</h4>
      <div className="cart-container">
        <div className="space2"></div>
        <div className="product-icon">
          <a className="cart" onClick={() => addToCart(product)}>
            <FaCartPlus />
          </a>
        </div>
      </div>
    </li>
  ))}
}

If that doesn't solve, look at the other possible reasons here and troubleshoot: React - Cannot read property 'map' of undefined[^]
 
Share this answer
 
Comments
h311o 12-Nov-20 2:44am    
@SandeepMewara okay, I did it like this:
<ul className="flex cards">
          {if (products) {
            products.map((product, index) => (
            <li key={index}>
              <h2>{product.name}</h2>
              <div className="space3"></div>
              <img src={product.image} alt={product.name} />
              <div className="space"></div>
              <div className="buy-product">
                <button onClick={() => (window.location.href = product.link)}>
                  Buy
                </button>
              </div>
              <h4>${product.cost}</h4>
              <div className="cart-container">
                <div className="space2"></div>
                <div className="product-icon">
                  <a className="cart" onClick={() => addToCart(product)}>
                    <FaCartPlus />
                  </a>
                </div>
              </div>
            </li>
          ))
          }}
        </ul>

And it says: 'Expression expected.'
Sandeep Mewara 12-Nov-20 2:51am    
Thats not the way. You gave a snippet so I updated that. clearly there is more code to what you shared. (your code wouldnt be just ul tags, there would be more.)

Please adjust the logic - you need to check for products being null. OR define a dummy/empty value.
h311o 12-Nov-20 2:55am    
Oh...sorry, I thought I just had to share the bit where the code was. I've updated the question now.
Sandeep Mewara 12-Nov-20 4:30am    
You will return only if products is there or else not go into that code.

if(products){
// your current return code
return ....
}
h311o 12-Nov-20 21:35pm    
I tried that:

Hide   Expand   Copy Code
if (item) {    return (      <div className="products">        <h1 className="big-text">Games</h1>        {/* Cards */}        <div className="products">          <ul className="flex cards">            {products.map((product, index) => (              <li key={index}>                <h2>{product.name}</h2>                <div className="space3"></div>                <img src={product.image} alt={product.name} />                <div className="space"></div>                <div className="buy-product">                  <button onClick={() => (window.location.href = product.link)}>                    Buy                  </button>                </div>                <h4>${product.cost}</h4>                <div className="cart-container">                  <div className="space2"></div>                  <div className="product-icon">                    <a className="cart" onClick={() => addToCart(product)}>                      <FaCartPlus />                    </a>                  </div>                </div>              </li>            ))}          </ul>        </div>      </div>    );  }


And it still doesn't work. (This code is after useEffect() by the way.)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900