loop doesn't work inside `onreadystatechange`

597 views Asked by At

here is my code:

xmlhttp.onreadystatechange = function () {

              if (this.readyState == 4)

                  if( this.status == 200) {
                  response = xmlhttp.responseXML;
                  var channel = response.documentElement;
                  var title = channel.getElementsByTagName("title")[0].firstChild.nodeValue;

                  var parent =  document.getElementById("journalTitle");
                  parent.innerHTML = title;

                  var articleList = document.getElementById("articleList");

                  item = channel.getElementsByTagName("item");
                  var list = new Array();
                  itemSize = (channel.getElementsByTagName("item").length);
                  var i =0;
                  do{

                      list[i] = item[i].getElementsByTagName("title")[0].firstChild.nodeValue;

                      item = document.createElement("div");
                      item.innerHTML = list[i];
                      articleList.appendChild(item);
                      i++;


                  }while(i=itemSize);

                } 

the size variable is 22 and when I write alert(item[5].getElementsByTagName("title")[0].firstChild.nodeValue); it shows me the fifth element and so on, but inside the loop it just understand the first element of item for the rest it returns error :

Uncaught TypeError: Cannot call method 'getElementsByTagName' of undefined

3

There are 3 answers

1
Paniz On BEST ANSWER

I found my problem so ridiculous. although the while was incorrect, the for didn't work neither. the problem was that I have used different variables with the same name item . the problem was solved when I changed the code like so:

xmlhttp.onreadystatechange = function () {

          if (this.readyState == 4)

              if( this.status == 200) {
              response = xmlhttp.responseXML;
              var channel = response.documentElement;
              var title = channel.getElementsByTagName("title")[0].firstChild.nodeValue;

              var parent =  document.getElementById("journalTitle");
              parent.innerHTML = title;

              var articleList = document.getElementById("articleList");

              item = channel.getElementsByTagName("item");
              var list = new Array();
              itemSize = (channel.getElementsByTagName("item").length);

              for (i = 0;i<itemSize;i++){

                  list[i] = item[i].getElementsByTagName("title")[0].firstChild.nodeValue;

                  itemD = document.createElement("div");
                  itemD.innerHTML = list[i];
                  articleList.appendChild(itemD);


              }

            } 
 } 
0
Teemu On

Your condition in the while loop is not comparing anything. It's a definition, setting the value of i to itemSize (which is 22 according to OP). If this wouldn't cause an error later in the script, you'd have an infinite loop, since 22 is evaluated to true in the condition of while.

The body of the do...while loop is always executed at least once. On the first round, i is 0, and you get the expected results. However, when the second round begins, i equals to 22, since it has got a new value in the while(i=itemSize).

getElementsByTagName() returns an array-like object, which has zero-based indexing, i.e. the largest index in the item is 21. On the second round of the loop you're trying to use getElementsByTagName method of undefined (item[22].getElementsByTagName(...)..., this causes the error message.

There's also a naming collision in the loop (the original item list is replaced with a DOM element), though this might be just a typo in the post. However, if the variable will be renamed, the indexing issue would remain.

I'd suggest you to use a for loop instead of do...while, just in case, there wouldn't be any items in item:

for (i = 0; i < itemSize; i++) {
    list[i] = item[i].getElementsByTagName("title")[0].firstChild.nodeValue;
    itemEl = document.createElement("div"); // renamed the variable
    itemEl.innerHTML = list[i];
    articleList.appendChild(itemEl);
}
0
Ringo On
xmlhttp.onreadystatechange = function () {

              if (this.readyState == 4)

                  if( this.status == 200) {
                  response = xmlhttp.responseXML;
                  var channel = response.documentElement;
                  var title = channel.getElementsByTagName("title")[0].firstChild.nodeValue;

                  var parent =  document.getElementById("journalTitle");
                  parent.innerHTML = title;

                  var articleList = document.getElementById("articleList");

                  item = channel.getElementsByTagName("item");
                  var list = new Array();
                  itemSize = (channel.getElementsByTagName("item").length);
                  var i =0;
                  do{

                      list[i] = item[i].getElementsByTagName("title")[0].firstChild.nodeValue;

                      item = document.createElement("div");
                      item.innerHTML = list[i];
                      articleList.appendChild(item);
                      i++;


                  }while(i=itemSize);

                } 
} /*<---missing bracket here*/