Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call an ajax function in a for loop [duplicate]

I'm new to ajax and JavaScript. What am trying to do is to call an ajax function several times to fetch certain data from a resource and then "push" all of the data into an array so that I can use it later on in the code. Here is my code.

var arr = [];
var users = ["brunofin", "comster404", "ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

for (i = 0; i < users.length; i++) {
    $.ajax({
        url: "https://api.twitch.tv/kraken/streams/" + users[i],
        success: function(data) {
            arr.push(data);
        },
        error: function(data) {
            arr.push("blank");
        },
        complete: function() {
            if (i == users.length) {
                console.log(arr); //This seem to print even when the condition isn't true
            }
        }
    });
}

The problem with the code is that, it prints to the console even when i isn't equal to users.length

My question is; how do I make certain that it waits until i == users.length is true before it prints to the console? Please keep in mind that I still desire the process to be asynchronous.

like image 422
Fortune Avatar asked Dec 15 '22 04:12

Fortune


2 Answers

Here is how you can call all requests considering their success without running an request over another:

var arr = [];
var users = ["brunofin", "comster404", "ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

var runRequests = function(userIndex) {
  if (users.length == userIndex) {
    console.log("runRequests Success", arr);
    return;
  }

  var user = users[userIndex];

  $.ajax({
    url: "https://api.twitch.tv/kraken/streams/" + user,
    success: function(data) {
      arr.push(data);
    },
    error: function() {
      arr.push({});
      console.error("runRequests Error", "user", arguments);
    },
    complete: function() {
      runRequests(++userIndex);
    }
  });
};

runRequests(0);

Working demo

like image 103
DontVoteMeDown Avatar answered Dec 21 '22 10:12

DontVoteMeDown


This happens because of the asynchronous nature. By the time the ajax callbacks are called, i == user.length is already true. But in your case you can just change:

if (i == users.length) {

to:

if (arr.length == users.length) {

This will also work nice if the callbacks are not executed in the same order as you initiated the ajax requests.

like image 44
trincot Avatar answered Dec 21 '22 11:12

trincot