0

I'm trying to store a list of items in localstorage using hooks and state like . but it returns an error

TypeError
cartList is not iterable

this is my code: (and this is the codesandbox)

import { useState, useEffect } from "react";
import { Button } from "react-bootstrap";

export default function App() {
  const [cartList, setCartList] = useState([]);
  const [cartItem, setCartItem] = useState([]);

  useEffect(() => {
    let localCart = localStorage.getItem("cartList") || "{}";
    console.log("localcart", localCart);
    if (localCart) {
      localCart = JSON.parse(localCart);
    }
    setCartList(localCart);
  }, []);

  const handleClick = (e, item) => {
    e.preventDefault();

    const arr = e.target.id.split("-");
    const selectID = arr[1];
    console.log("selectID", selectID);
    setCartItem({ ...cartItem, id: selectID });
    console.log("cartItem", cartItem);

    let itemIndex = -1;
    for (const entry of Object.entries(cartList)) {
      console.log("entry", entry);
    }
    if (itemIndex < 0) {
      setCartList([...cartList, cartItem]); // error occurs here according to codesandbox
      localStorage.setItem("cartList", JSON.stringify(cartList));
    }
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Button
        variant="link"
        id="item-12"
        onClick={(e) => handleClick(e, cartItem)}
      >
        item no.12
      </Button>
      <Button
        variant="link"
        id="item-100"
        onClick={(e) => handleClick(e, cartItem)}
      >
        item no.100
      </Button>
    </div>
  );
}
1
  • 1
    You initialize cartList as an Array, but then set it as an Object if not found in localStorage let localCart = localStorage.getItem("cartList") || "{}";. Objects aren't iterable, and setting it as a string to be parsed manually is odd. You need let localCart = localStorage.getItem("cartList") || "[]"; but I would recommend just skipping the parse if not found in localStorage. Commented Jun 18, 2022 at 9:28

3 Answers 3

1

Why you are getting TypeError: cartList is not iterable is because you have initialized the cartList incorrectly.

Please have a try in console following snippet, You will face exactly same error.

console.log( [...{ prop: 'value' }] )

So you should initialize cartList as [] rather than {} inside the useEffect hook like the following.

let localCart = localStorage.getItem("cartList") || "[]";
Sign up to request clarification or add additional context in comments.

Comments

1

I think you are confusing about a type of cartList. I guess it would be an Array.

const [cartList, setCartList] = useState([]); // It is declared as Array
 useEffect(() => {
    let localCart = localStorage.getItem("cartList") || "{}"; // But initialized as Object this line
    console.log("localcart", localCart);
    if (localCart) {
      localCart = JSON.parse(localCart);
    }
    setCartList(localCart);
  }, []);
 if (itemIndex < 0) {
    setCartList([...cartList, cartItem]); // It should be an Array, but error occured as it's an Obejct.
    localStorage.setItem("cartList", JSON.stringify(cartList));
 }

1 Comment

You have pointed out the problem but not shown the solution. (get rid of the || '{}' and move the setCartList inside the if block.)
0

As @pilchard pointed out, you are setting cartList as an object on that line:

localStorage.getItem("cartList") || "{}";

So on first render before setting the carlist value to localstorage you are setting the state as an object which cannot be spread inside an array

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.