0

I wonder how async call works when looping through html elements with jquery. I know that async call doesn't stop iterating when server call is being made. That means, script is immediately iterating over next element in sequence, even if response from call is not yet finished.

My problem is, that on each call I have different values set, like this:

$(".businessUnit").each(function (index) {
      var $element = $(this);
      var iUCBU_KEY = $element.prop('data-iucbu_key');
      var iENTE_KEY = $element.prop("data-iente_key");

$.ajax({
      method: 'post',
      url: '/CodeBase/LoadInsertCATETE_BASE1/',
      data: {
        iUCBU_KEY: iUCBU_KEY,
        iENTE_KEY: iENTE_KEY
      },
      success: function (response) {
        //will there be $element from sequence when call was made?
          $element.find('input.price').val(response.price);

      },
      error: function (response) {

      }
    });      
});

Which $element will be updated? Will it be $element from which call was made or $element in which iteration is currently? Response from server can take a few seconds, so iteration can go several elements further in between call - response.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
FrenkyB
  • 6,625
  • 14
  • 67
  • 114
  • 2
    it will be the current iteration value - each iteration has its own `var`s – Jaromanda X Sep 12 '19 at 08:33
  • 1
    Regardless of the state of `$element` you should not be making AJAX requests in a loop as you'll flood your server. Aggregate all data in to a single request instead. – Rory McCrossan Sep 12 '19 at 08:35
  • @JaromandaX - that means I will update wrong element? – FrenkyB Sep 12 '19 at 08:36
  • 1
    no, that means you update the right one ... think of each iteration being an independant call to the callback ... because, well, that's what is happening – Jaromanda X Sep 12 '19 at 08:38
  • 1
    `var $element` stays the same for the lifetime of that iteration. So the `success: $element` is the same $element that was set at the top - for each iteration. Doesn't matter that it "runs" later. If you put `$element` *outside* the loop, then all of the success callbacks would use the last one. – freedomn-m Sep 12 '19 at 08:39
  • @freedomn-m - that means javascript is putting those values on the stack or some other temporary storage? – FrenkyB Sep 12 '19 at 08:39

1 Answers1

2

The $element in the ajax call will have the value it had when the ajax call was issued.

That's because the callback used in the .each( forms a closure over its whole content.

If you were to do something like:

const businessUnits = $(".businessUnit");

for (let i = 0; i < businessUnits.length; i++){
    var $element = $( businessUnits[i] );
.
.
.
    $.ajax(....)
}

Then the value of $element would have most probably been the last element.

Tudor Constantin
  • 26,330
  • 7
  • 49
  • 72