forEach is not a function error with JavaScript array
I'm trying to make a simple loop:
const parent = this.el.parentElement
console.log(parent.children)
parent.children.forEach(child => {
console.log(child)
})
But I get the following error:
VM384:53 Uncaught TypeError: parent.children.forEach is not a function
Even though parent.children
logs:
What could be the problem?
Note: Here's a JSFiddle.
Solution 1:
First option: invoke forEach indirectly
The parent.children
is an Array like object. Use the following solution:
const parent = this.el.parentElement;
Array.prototype.forEach.call(parent.children, child => {
console.log(child)
});
The parent.children
is NodeList
type, which is an Array like object because:
- It contains the
length
property, which indicates the number of nodes - Each node is a property value with numeric name, starting from 0:
{0: NodeObject, 1: NodeObject, length: 2, ...}
See more details in this article.
Second option: use the iterable protocol
parent.children
is an HTMLCollection
: which implements the iterable protocol. In an ES2015 environment, you can use the HTMLCollection
with any construction that accepts iterables.
Use HTMLCollection
with the spread operatator:
const parent = this.el.parentElement;
[...parent.children].forEach(child => {
console.log(child);
});
Or with the for..of
cycle (which is my preferred option):
const parent = this.el.parentElement;
for (const child of parent.children) {
console.log(child);
}
Solution 2:
parent.children
is not an array. It is HTMLCollection and it does not have forEach
method. You can convert it to the array first. For example in ES6:
Array.from(parent.children).forEach(child => {
console.log(child)
});
or using spread operator:
[...parent.children].forEach(function (child) {
console.log(child)
});
Solution 3:
A more naive version, at least you're sure that it'll work on all devices, without conversion and ES6 :
const children = parent.children;
for (var i = 0; i < children.length; i++){
console.log(children[i]);
}
https://jsfiddle.net/swb12kqn/5/
Solution 4:
parent.children
will return a node list list, technically a html Collection. That is an array like object, but not an array, so you cannot call array functions over it directly. At this context you can use Array.from()
to convert that into a real array,
Array.from(parent.children).forEach(child => {
console.log(child)
})
Solution 5:
parent.children
is a HTMLCollection
which is array-like object. First, you have to convert it to a real Array
to use Array.prototype
methods.
const parent = this.el.parentElement
console.log(parent.children)
[].slice.call(parent.children).forEach(child => {
console.log(child)
})