Uncaught TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator)) in my React project

Matthew C.
jump to solution

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 useContext React 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.

Sentry