SilentDesigns
SilentDesigns

Reputation: 575

Iterating through HTMLcollection in React,js

I am having trouble iterating through and HTMLCollection in a React.js component. I have the following function:

shuffleLists = () => {
        var elems = document.getElementsByTagName("ul");
        console.log(elems)

        for (let item of elems) {
          console.log(item);
        }   
    }

console.log(elems) prints out an HTMLCollection of ul elements as expected. But the for loop after it doesn't print anything in the console, when I would expect to see each ul element printed in the console. What am I doing wrong?

Edit for clarity:

The key issue here is that the line console.log(item) inside the loop does not output anything into the console in chrome dev tools, and the same applies to other various loop syntaxes as discussed in the answers and comments below.

I also have noticed that there is different lengths being logged from console.log(elems) between different browsers. In chrome I see HTMLCollection[] length: 10 ... But in Firefox I see HTMLCollection {length 0} ...

Upvotes: 3

Views: 8775

Answers (3)

SilentDesigns
SilentDesigns

Reputation: 575

I figured out my problem was that I was calling the shuffleLists function from the parent component in React, prior to the ul and li elements I wanted to iterate through being rendered in the sub-component. The console output for the elems var was confusing as it showed all the lists and list items inside the HTMLCollection.

When I moved the shuffleLists function to the sub-component and called it inside componentDidMount I was able to loop through and console out all the list items as desired.

Upvotes: 2

Akshit Mehra
Akshit Mehra

Reputation: 767

The item in your for loop is actually the key (array index). You need to get the particular element from the elems array by using the syntax elems[item].

Refactoring your code (and changing item to key, just for clarity):

shuffleLists = () => {
        var elems = document.getElementsByTagName("ul");
        console.log(elems);

        for (let key of elems) {
          console.log(elems[key]);
        }   
    }

UPDATE: because result of getElementsByTagName() is a NodeList

shuffleLists = () => {
        var elems = document.getElementsByTagName("ul");
        console.log(elems);

        elems.forEach(function(val) {
          console.log(val);
        })
    }

From the MDN Web Docs

Although NodeList is not an Array, it is possible to iterate over it with forEach(). It can also be converted to a real Array using Array.from().

However, some older browsers have not implemented NodeList.forEach() nor Array.from(). This can be circumvented by using Array.prototype.forEach().

As per the updated requirement of the OP

shuffleLists = () => {
        var ulElems = document.getElementsByTagName("ul");
        console.log(ulElems);

        for(i = 0; i < ulElems.length; i++) {
            var liElems = ulElems[i].getElementsByTagName("li");
            for(j = 0; j < liElems.length; j++) {
                console.log(liElems[j].innerHTML);
            }
        }
    }

Upvotes: 3

ROOT
ROOT

Reputation: 11622

document.getElementsByTagName will return an array of elements, in your case array of elements in the page, so you need to have something like the following if you want to have the first ul

shuffleLists = () => {
    var elems = document.getElementsByTagName("ul");
    console.log(elems)

    for (let idx of elems) {
      console.log(elems[idx]);
    }   
}

I would suggest to use document.getElementById() to be more precise about your selected elements

Upvotes: 1

Related Questions