0

I'm a relative newbie to javascript and I'm trying to make multiple ajax calls within a for loop. It loops through the elements of an array using a different url for an ajax call each time it goes through the loop. The problem is that the value of the variable 'test' is always equal to "condition4". I'm used to other languages where the value of 'test' would be "condition1", then "condition2" etc as it goes through the for loop. Here is a simplified version of my code:

var myData = [];
var cnt = 0;
var link;
var myCounter = 0;
var myArray = ["condition1", "condition2", "condition3", "condition4"];

for (x = 0; x < myArray.length; x++) {
    link = "https://test.com/" + myArray[x];
    myCounter = x;
    GetJSON(function (results) {
        for (i = 0; i < results.data.length; i++) {
            var id = results.data[i].identifier;
            var test = myArray[myCounter];
            myData[cnt] = { "id": id, "test": test };
            cnt++;
        }
    });
}

function GetJSON(callback) {
    $.ajax({
        url: link,
        type: 'GET',
        dataType: 'json',
        success: function (results) {
            callback(results);
        }
    });
}
2
  • It's the same old story, JS binds by name. Create a new scope, or avoid closuring the local vars by passing them along by using, say, context. Commented Jan 17, 2017 at 12:33
  • It's because your ajax calls are being done asynchronously so by the time your success has happened, the loop will have got to 4 so all your results will be 4 Commented Jan 17, 2017 at 12:33

2 Answers 2

1

I think you can solve this issue by sending and receiving myCounter value to server

for (x = 0; x < myArray.length; x++) {
  link = "https://test.com/" + myArray[x];
  myCounter = x;
  $.ajax({
    url: link,
    type: 'GET',
    dataType: 'json',
    data: { myCounter: myCounter}
    success: function(results) {
      for (i = 0; i < results.data.length; i++) {
        var id = results.data[i].identifier;
        var test = results.data[i].myCounter
        myData[cnt] = {
          "id": id,
          "test": test
        };
        cnt++;
      }
    }
  });

}

Sign up to request clarification or add additional context in comments.

Comments

1

When you are executing the loop, it attaches the myCounter reference. Then, due to the async task, when it finishes and call 'myCounter', it has already achieved the number 4. So, when it call 'myCounter', it is 4. To isolate the scope, you need to create a new scope every iteration and isolating each value of 'myCounter'

for (x = 0; x < myArray.length; x++) {
    link = "https://test.com/" + myArray[x];
    myCounter = x;
    //IIFE
    (function() {
      var ownCounter = myCounter; //Isolating counter
      GetJSON(function (results) {
        for (i = 0; i < results.data.length; i++) {
            var id = results.data[i].identifier;
            var test = myArray[ownCounter];
            myData[cnt] = { "id": id, "test": test };
            cnt++;
        }
      });
      
    })();
    
}

Or...

for (let x = 0; x < myArray.length; x++) {
    link = "https://test.com/" + myArray[x];
    myCounter = x;
    
    GetJSON(function (results) {
      for (i = 0; i < results.data.length; i++) {
          var id = results.data[i].identifier;
          var test = myArray[x];
          myData[cnt] = { "id": id, "test": test };
          cnt++;
      }
    });
     
        
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.