Uncaught TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator)) in my React project
The Problem
You encounter the following error message when building a React application:
Uncaught TypeError: myobj is not iterable (cannot read property Symbol(Symbol.iterator))
The Solution
This type of JavaScript error, TypeError: ‘x’ is not iterable, occurs when a non-iterable object is used instead of an iterable object.
You can resolve this error by ensuring you haven’t used a non-iterable object when an iterable object is expected, such as in the following common scenarios:
- Using destructuring assignment syntax
- Looping over a JavaScript
Object - Accessing a context value with the
useContextReact hook
Using the Incorrect Destructuring Syntax
A common cause for the object-is-not-iterable error is the use of array destructuring assignment syntax on a non-iterable object:
const myObj = { prop1: {}, prop2: [42] };
const {
prop1: [value1], // {} is not iterable
prop2: [value2],
} = myObj;
When using destructuring assignment syntax, be careful not to confuse curly braces {} with square brackets [].
-
If you are using array destructuring, ensure you use an array (with square brackets):
const myObj = { name: ["Gerald"] }; const { name: [value], } = myObj; console.log(value); // Gerald -
If you are using object destructuring, ensure you use an object (with curly braces):
const myObj = { name: { first: "Gerald" } }; const { name: { first }, } = myObj; console.log(first); // Gerald
Looping Over a JavaScript Object
The object-is-not-iterable error also commonly occurs when you try to loop over a JavaScript Object, which is not iterable:
for (const item of myObj) {
console.log(item);
}
Using Incorrect Destructuring Syntax With the useContext React Hook
In React, the object-is-not-iterable error often occurs when using Context.
In the example code below, the context provider value, which can be of any type, is an object that contains the state value object:
import { createContext, useState } from "react";
export const GlobalContext = createContext();
export default function GlobalProvider({ children }) {
const [state, setState] = useState({ name: "Gerald" });
return (
<GlobalContext.Provider
value={{
state,
}}
>
{children}
</GlobalContext.Provider>
);
}
The useContext hook is used to get this context value in a component that is wrapped with the context provider:
const [ globalState ] = useContext(GlobalContext);
However, running the above code causes the following error:
Uncaught TypeError: useContext is not a function or its return value is not iterable
This error occurs because you can’t destructure an object using array destructuring.
When using the useContext React hook to access a context value, ensure that you use the correct destructuring assignment syntax.
If the context value is an object, use object destructuring:
const { globalState } = useContext(GlobalContext);
Notes
An iterable object has values that can be looped over, such as an Array, String, Map, or Set object. Strings are primitive, but they can be created as objects using the String() constructor.
An iterable object must implement the [Symbol.iterator]() method. This method returns the iterator for the object, which is used to obtain the values to be iterated.
Considered "not bad" by 4 million developers and more than 150,000 organizations worldwide, Sentry provides code-level observability to many of the world's best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.