0
function updateStrandDataOnPage(strands, cableID){
    console.log(strands);
    var tubesOnPage = document.getElementsByClassName("tube");
    console.log(tubesOnPage);

    if(strands.length != 0){
        for(var i=0; i<tubesOnPage.length; i++){
            tubesOnPage[i].name = strands[i].tube_id;
            tubesOnPage[i].value = strands[i].num_of_strands;

            // Make call to server to get individual strand information
            var xhr = new XMLHttpRequest();
            var xhrURL = "/strand/strandInfo/" + strands[i].tube_id;
            xhr.open('GET', xhrURL, true);
            // xhr.responseType = 'json';

            xhr.onreadystatechange = function(){
                if(this.readyState == 4 && this.status == 200){
                    console.log(xhr.response);
                    var table = makeTable()
                    console.log(colors);  // ===== remove this

                    ///// PROBLEM HERE //////
                    for(var j=0; j<strands[i].num_of_strands; j++){
                        addRows(table, strands[i].tube_id, colors);
                    }

                    ///// PROBLEM HERE ///////
                    tubesOnPage[i].parentNode.parentNode.appendChild(table);
                }
                if(this.status != 200){
                    console.log(xhr.response, this.status);
                }
            }
            xhr.send();
        }
    }
    else{
        for(var i=0; i<tubesOnPage.length; i++){
            tubesOnPage[i].value = 0;
        }
    }
}

Here when I try to access DOM with i which is defined in the for loop above it gives me an error: "cannot read property of undefined ". As far as I know scope is inherited if a function is defined inside a function.

May be I am missing a scope concept!

  • The variable `i` is shared by all the callbacks. – Pointy Mar 19 '17 at 01:34
  • But I do not have any callbacks! Even if it is shared why do I get undefined error? – Jayant Arora Mar 19 '17 at 01:35
  • Is there a scope concept that I might be missing? – Jayant Arora Mar 19 '17 at 01:37
  • *"But I do not have any callbacks!"* - Yes you do. (Your `onreadystatechange` handler, of which you have multiple instances.) By the time those handlers are called the loop has finished and `i` is equal to `tubesOnPage.length`, so `tubesOnPage[i]` is past the end of the array and `undefined`. – nnnnnn Mar 19 '17 at 01:39
  • You definitely have a callback - what do you think the "onreadystatechange" function is? – Pointy Mar 19 '17 at 01:40
  • This is a frequently asked question. But unless you know the answer you may not be able to search for it. http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example If you can guarantee browser support of `let`, simply change `for(var i=0;` to `for(let i=0;` – traktor Mar 19 '17 at 01:48
  • Now I get it. That the value of i becomes undefined because onreadystatechange is actually a callback. – Jayant Arora Mar 19 '17 at 01:58
  • 1
    No, `i` *is* defined. It is `tubesOnPage[i]` that is undefined. – nnnnnn Mar 19 '17 at 02:10
  • The for loop only works for the last iteration! How should I fix it to make it work for first iterations. Is it because it's asynchronous? – Jayant Arora Mar 19 '17 at 16:55

0 Answers0