Easy fix: TypeError: forEach is not a function in JavaScript
The "Uncaught TypeError: x.forEach is not a function" error caught you. The solution is straightforward. You probably distracted and missed the obvious.
JavaScript has many data structures and object types; even experienced developers get this error when distracted or tired. I remember times when I was looking at the monitor, scratching my head, and didn't realize the obvious mistake:
I try to access forEach method of an object (i.e., plain old object, array-like object, global object, etc.) instead of an array. That's it.
The error thrown may be different based on your environment. For example, Node.js throws TypeError: x.forEach is not a function error
, and browsers throw Uncaught TypeError: x.forEach is not a function error
. However, solutions are the same. Below I explained the most frequently encountered mistakes. After you see the similarities in the root causes, you will get the idea and quickly fix this error, whatever the reason is.
array-like-object
An array-like is an object with positive integer keys and length attributes. It is not a JavaScript array. It doesn't have array functions, so the forEach
function is unavailable.
const arrayLike = { 0: "pencil", 1: "ruler", length: 2 }; // You can't use forEach() with this.
I frequently make this mistake when I use functions to get dom elements in front-end code that return an array-like object instead of an array. My mind automatically assumes that the incoming data is an array of objects, and boom, I got runtime errors!
The following code illustrates the above errors. You get an HTML Collection and try to
I use modern javascript in the examples to utilize pretty features of ES (i.e., callback functions are written as arrow functions).
const mistakenlyAssumedArray = document.getElementsByTagName('div');
mistakenlyAssumedArray.forEach(el => console.info(el.name)); // TypeError: mistakenlyAssumedArray.forEach is not a function.
Fix
The following code example will use the static JavaScript array method from()
to get a real array. As a result, we can access the forEach
function to process each array element.
Array.from(arrayLike).forEach(el => console.info(el));
Usually, front-end code returns array-like objects, but it can be produced anywhere. If you are unsure whether your input would be a real array or an array-like object, you can use the above example as a defensive code.
Plain Object
When writing code like I'm on fire, my hand sometimes acts before my brain. I want to loop through key-value pairs of the object but write the following code:
const item = { id: 1, name: "pencil", color: "red" };
item.forEach(key => console.info(key)); // Ooops! TypeError: item.forEach is not a function.
Fix
Whereas I should write the example code below, get all key-value pairs as array elements:
const item = { id: 1, name: "pencil", color: "red" };
Object.keys(item).forEach(key => console.info(key));
Object.entries(item).forEach(([key, value]) => console.info(key, value));
JSON Object (Actually JSON Array)
I've never written this code myself, but one time during a code review, I wasted too much time trying to find this simple mistake right in front of me. The code I reviewed is very similar to the code example below, including the names of the variables. The error below would never happen if the code were written using TypeScript. (Shameless advocation)
const items = await fetchItems(); // Returns JSON array as string: `["pencil", "ruler"]`
items.forEach(item => console.info(item)); // Again! TypeError: item.forEach is not a function.
Fix
I would not write the solution here and leave it to you. Have you found it? Raise your voice and write your answer in the comments below. Also, you could mention other silly mistakes you made during the development. I wonder whether I'm the only developer who makes foolish mistakes.
Comments ()