Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

using .forEach() instead of a normal for loop

I wanted to use .forEach() to loop through an array of LI elements using this code:

 const listDiv = document.querySelector('.list');
 const listUl = listDiv.querySelector('ul');
 const listElement = listUl.children;

 function attachListItemButtons (li) {

     let up = document.createElement('button'); 
     up.className = 'up'; 
     up.textContent = 'Up'; 
     li.appendChild(up);

     let down = document.createElement('button'); 
     down.className = 'down'; 
     down.textContent = 'Down'; 
     li.appendChild(down);

     let remove = document.createElement('button'); 
     remove.className = 'remove'; 
     remove.textContent = 'Remove';
     li.appendChild(remove);
 }

 listElement.forEach(attachListItemButtons);

but i get this error "Uncaught TypeError: listElement.forEach is not a function"

if I use

 const listElement = listDiv.querySelectorAll('ul li'); 

instead of

 const listElement = listUl.children;

the .forEach() works properly.

I noticed that if I console.log listElement i get an array but the first one has a proto of HTMLCollection the second one a proto of NodeList

they are anyway both arrays so if a normal for works why the .forEach doesn't work in the first case?

Thanks

3 Answers

Hi Fabio,

So .children returns as an HTML Object, and the way you would access that object, like any object, is by cycling through the objects using object.length and selecting each index value.

Selecting all the li elements returns as an array, so using a .forEach() function is fine. You can use .children still, but I would set up a typical for loop using listElement.length instead.

Hope this helps :) Check out the documentation on .children (https://www.w3schools.com/jsref/prop_element_children.asp) for more info

From what I could tell from the MDN, the differentiation is that HTMLCollection doesn't have a forEach() method.

Perfect, thank you for the quick replies guys!