1

I need to send multiple get requests in a loop, and the callback that processes the response needs the index of the loop in order to combine the response data with the data I already had about each object.

From this, I know how to create a single request and use a callback to pass extra parameters. I am also able to send multiple requests and use XMLHttpRequest.onreadystatechange to set a function for the result.

I tried combining the two solutions, but because it's a loop, the variables change after each iteration and all the responses end up being called with the parameters of the last iteration of the loop. I thought using var indexOfProject = i; inside the loop would solve the problem, but it didn't. Here's my code:

var count = 0;
var queryProjects = 2;
var totalNeeded = queryProjects;

var apicallback = function(project, index) {
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {  
        console.log("processing response, index, project : " + index);
        console.log(project);
        var objResponse = JSON.parse(xmlHttp.responseText);
        _projectsData.projects[index]['lastUpdateTime'] = objResponse['updated_at'];
        count++;
        if (count==totalNeeded){
            console.log("got all responses!");
            //TODO: 
        }
    }
};

for (var i = 0; i < queryProjects; i++) {
    var indexOfProject = i;
    if (repos[i] != null) {
        var theUrl = "https://api.github.com/repos/" + repos[i][0];
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() { 
            apicallback(_projectsData.projects[indexOfProject], indexOfProject); 
        }
        console.log("sent request!");
        xmlHttp.open("GET", theUrl, true); // true for asynchronous 
        xmlHttp.send(null);
    }
    else {
        totalNeeded--;
    }
}

I also tried this,

xmlHttp.onreadystatechange = apicallback(_projectsData.projects[indexOfProject], indexOfProject); 

but it was even worse because the callback is only called once, when readystate==1.

8
  • stackoverflow.com/questions/750486/… Commented Feb 1, 2019 at 12:58
  • Easiest thing, break it out into a function and call it with the loop varaible. Commented Feb 1, 2019 at 12:59
  • @epascarello The parameters are working now, but the callback seems to run twice for some of my entries. And I mean twice with xmlHttp.readyState == 4 being true, which messes up with my data. Of course I can handle duplicates, but it also looks like for some of the entries the callback doesn't run at all. This problem didn't occur before. Any ideas? Commented Feb 1, 2019 at 15:26
  • Did you add console.log statements to see what the xmlHttp.status is? Commented Feb 1, 2019 at 15:30
  • Yes. the readystate usually goes through all values from 1 to 4, and status starts with 0 and becomes 200 after readystate is 2. It also looks like the entry that doesn't trigger is always the same, but it runs fine on its own. Commented Feb 1, 2019 at 15:37

0

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.