How to Resolve "TypeError: .forEach is not a function" Error in JavaScript
The TypeError: x.forEach is not a function is a common error that occurs when you try to call the .forEach() method on a value that is not an array (or another iterable type that supports it, like a NodeList or a Map). This typically happens when you mistakenly believe a variable holds an array, but it actually holds an object, null, undefined, or an array-like HTMLCollection.
This guide will explain the common causes of this error and show you the correct ways to solve it by either guarding your code or using the right method to iterate over your specific data type.
The Core Problem: .forEach() is Not a Universal Method
The .forEach() method is designed to iterate over collections. In JavaScript, it is a built-in method on the prototypes of:
ArrayMapSetNodeList(returned byquerySelectorAll)
Crucially, it does not exist on plain Objects or on array-like but non-iterable HTMLCollections (returned by older methods like getElementsByClassName).
Cause 1 (Most Common): The Variable is an Object
This is the most frequent source of the error. You have a plain JavaScript object and you try to iterate over it as if it were an array.
Example of problem:
// Problem: `user` is an object, not an array.
let user = {
name: 'Alice',
id: 123,
};
// ⛔️ TypeError: user.forEach is not a function
user.forEach((value, key) => {
console.log(key, value);
});
Solution: to iterate over an object, you must first convert its keys, values, or entries into an array.
1. Iterate Over Keys (Most Common):
Object.keys(user).forEach(key => {
console.log(key, user[key]);
});
Output:
name Alice
id 123
2. Iterate Over Values:
Object.values(user).forEach(value => {
console.log(value);
});
Output:
Alice
123
3. Iterate Over Key-Value Pairs (Entries):
Object.entries(user).forEach(([key, value]) => {
console.log(key, value);
});
Cause 2: The Variable is undefined or null
This happens when a variable you expect to be an array has not been initialized or was not found.
Example of problem:
let myList; // `myList` is currently `undefined`
// ⛔️ TypeError: Cannot read properties of undefined (reading 'forEach')
myList.forEach(item => {
console.log(item);
});
Solution: guard your code to ensure you only call forEach on a valid array. The simplest way is to provide a fallback empty array.
let myList;
// ✅ Correct: Use the nullish coalescing operator (`??`) to provide a fallback.
(myList ?? []).forEach(item => {
console.log(item);
});
Alternatively, an if check with Array.isArray() is also a robust solution.
if (Array.isArray(myList)) {
myList.forEach(item => { /* ... */ });
}
Cause 3: The Variable is an HTMLCollection
Older DOM methods like getElementsByClassName or getElementsByTagName return a live HTMLCollection. Unlike a NodeList (from querySelectorAll), an HTMLCollection does not have a forEach method.
Example of problem:
<div class="box"></div>
<div class="box"></div>
// Problem: `boxes` is an HTMLCollection, not an array or NodeList.
let boxes = document.getElementsByClassName('box');
// ⛔️ TypeError: boxes.forEach is not a function
boxes.forEach(box => {
box.style.color = 'red';
});
Solution: you must first convert the HTMLCollection into a true array.
1. Using Array.from() (Recommended):
let boxes = document.getElementsByClassName('box');
let boxesArray = Array.from(boxes);
boxesArray.forEach(box => {
box.style.color = 'red';
});
2. Using for...of (Simpler):
A for...of loop can iterate directly over an HTMLCollection, which is often cleaner than converting it to an array first.
let boxes = document.getElementsByClassName('box');
for (let box of boxes) {
box.style.color = 'red';
}
Practical Example: Iterating Safely
This function demonstrates a robust way to handle a value that could be an array or null/undefined.
function processList(list) {
// Use a fallback to ensure we're always working with an array.
let listToProcess = list ?? [];
listToProcess.forEach(item => {
console.log('Processing item:', item);
});
}
// Example Usage:
processList(['a', 'b']); // Works
processList(null); // Works, does nothing
processList(undefined); // Works, does nothing
Conclusion
The TypeError: .forEach is not a function is a clear signal that you are trying to use an array method on a value that is not a true array.
To solve it, follow this diagnostic process:
- Is your variable an object? If so, you must iterate over an array of its keys, values, or entries using
Object.keys(obj),Object.values(obj), orObject.entries(obj). - Is your variable
undefinedornull? Guard your code by providing a fallback empty array with the nullish coalescing operator:(myVar ?? []). - Is your variable an
HTMLCollection(fromgetElementsByClassName)? Convert it to an array withArray.from()or use afor...ofloop instead.