0

I wrote this JS code :

var abils = document.getElementsByName('aggiunta_abil');
for (let i = 0; i < abils.length; i++) {

  xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    alert(abils[i].parentNode.parentNode.innerHTML);

    if (xhttp.readyState == 4 || status == 200) {
      abils[i].parentNode.parentNode.innerHTML = this.responseText;
    }
  }

  var url = 'my url';

  if(abils[i].value != '') url = url + 'id_abil' + '=' + abils[i].value + '&';    
    xhttp.open('GET', url, true);
    xhttp.send();
  }
}

My problem is that the alert stamps correclty the innerHTML of the node, but 2 lines after it says me that abils[i] is not defined. Even if I remove the if clause , keeping only the 2 instructions one after the other one , nothing changes : the alert keep working well but the abils[i].parentNode.parentNode.innerHTML = this.responseText; no. I also tryed with jquery for ajax , but nothing change : in the success function it says me that abils[i] is not defined. I don't know what to do , please help me.

1 Answers1

0

Inside your for loop, make a copy of “i” in first line as, let j=i; And then, instead of using “i”, use “j” to access the element.see if it helps

highhope
  • 148
  • 10
  • I just saw that @CertainPerformance has mentioned the same. Please use that and let us know if it works. – highhope May 06 '18 at 11:50
  • It actually worked !! Thank you so much ! – Riccardo Paoletti May 06 '18 at 12:27
  • Can you explain me why please ? – Riccardo Paoletti May 06 '18 at 12:33
  • From what I understood, this behavior is because the function completes its “execution context” by the time response comes back and the variable “i” becomes length + 1 in memory. “Length + 1” is undefined. Hence we need to find a way to persist the value in memory for each loop. The keyword “let” will make copies of the variable in each “execution context “ of the function. “Execution context “ is created by the JS engine every time a function is executed. – highhope May 06 '18 at 12:46
  • oh , ok , i think i understood. Thank you – Riccardo Paoletti May 06 '18 at 13:07
  • So is there a way to make the loop wait that the response come back ? – Riccardo Paoletti May 06 '18 at 13:10
  • I don’t think we can make the loop wait because of the fact that JS engine is synchronous by nature. It executed all the code line by line. JS engine is single threaded. If that raises question in your mind about how async calls work, then just know that async calls are achieved by leveraging other components of the browser. JS engine is just one of the components in browser. – highhope May 06 '18 at 13:20
  • There's no need to introduce an extra variable. He can just change the `var i` to `let i`. – JLRishe May 06 '18 at 13:20
  • @JLRishe Agreed. This is much better. – highhope May 06 '18 at 13:21
  • mmm this is really bad , do you have any tips on how could i do the loop work ? – Riccardo Paoletti May 06 '18 at 13:27