Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use multiple XMLHttpRequest?

I need to get 8 JSON from 8 different URL. I stored the query string that I have to change in an Array and I loop through it with a for loop. Here is my code:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

var request = new XMLHttpRequest();

for (var i = 0; i < index.length; i++) {

    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onload = function() {
        var data = JSON.parse(request.responseText);
        console.log(data);
    }
    request.send();
}

So far I just want to display each JSON on the console. I don't get any error but I can display only the last JSON with the last index item (noobs2ninjas).

Could anybody explain me why? how do I get the all JSON that I need?

Thanks

like image 941
Dema Avatar asked Sep 30 '17 14:09

Dema


People also ask

How do I use XMLHttpRequest?

To send an HTTP request, create an XMLHttpRequest object, open a URL, and send the request. After the transaction completes, the object will contain useful information such as the response body and the HTTP status of the result.

How do I get HTML from XMLHttpRequest?

Retrieving an HTML resource as a DOM using XMLHttpRequest works just like retrieving an XML resource as a DOM using XMLHttpRequest , except you can't use the synchronous mode and you have to explicitly request a document by assigning the string "document" to the responseType property of the XMLHttpRequest object after ...

Is it safe to use XMLHttpRequest?

Both are equally insecure if you make the requests over unsecured connections. Both are equally secure if you make the requests over SSL connections. A request made over an SSL connection might (ultimately) be profoundly non-secure if you aren't protecting the data appropriately on the server, etc.

Is XMLHttpRequest a REST API?

As mentioned earlier, it's a Web API that lets you communicate with the server via a REST API endpoint to fetch data and then show it to the user without refreshing the page. You can also send data to the server in the background via this API.


3 Answers

Could anybody explain me why? how do I get the all JSON that I need?

In order to send a second request you need to wait for the first to finish. Hence, if you are interested to get the responses in the array order you can loop on each array element and only when you get the response you can loop on the remaining elements:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var request = new XMLHttpRequest();
(function loop(i, length) {
    if (i>= length) {
        return;
    }
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + i + ' id: ' + data._id);
            loop(i + 1, length);
        }
    }
    request.send();
})(0, index.length);

Instead, if you want to execute all the request completely asynchronous (in a concurrent way), the request variable must be declared and scoped inside the loop. One request for each array element. You have some possibilities like:

  • using let
  • declaring a callback
  • using IIFE
  • using array .forEach() instead of a for loop

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];


for (var i = 0; i < index.length; i++) {

    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    let request = new XMLHttpRequest();
    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + data._id);
        }
    }
    request.send();
}

As per @Wavesailor comment, in order to make a math computation at the end of calls:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var request = new XMLHttpRequest();
(function loop(i, length, resultArr) {
    if (i>= length) {
        console.log('Finished: ---->' + JSON.stringify(resultArr));
        return;
    }
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + i + ' id: ' + data._id);
            resultArr.push(data._id);
            loop(i + 1, length, resultArr);
        }
    }
    request.send();
})(0, index.length, []);
like image 63
gaetanoM Avatar answered Sep 21 '22 05:09

gaetanoM


The problem is that you declare

var request = new XMLHttpRequest();

outside of the for loop. So you instance only one request.

You have to include it inside the for loop.

Also, don't forget that ajax is executed asynchronous so you will get the results in a random order.

The value of i variable must be declared using let keyword in order to declare a block scope local variable.

let allows you to declare variables that are limited in scope to the block.

let is always used as a solution for closures.

Also, you can use an array where you can store the XMLHttpRequest.

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
requests=new Array(index.length);
for (let i = 0; i < index.length; i++) {
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];
    requests[i] = new XMLHttpRequest();
    requests[i].open("GET", url);
    requests[i].onload = function() {
        var data = JSON.parse(requests[i].responseText);
        console.log(data);
    }
    requests[i].send();
}
like image 45
Mihai Alexandru-Ionut Avatar answered Sep 17 '22 05:09

Mihai Alexandru-Ionut


You may also prefer to use the Fetch API in the place of XMLHttpRequest. Then all you have to do is to utilize a few Promise.all() functions.

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"],
    url   = "https://wind-bow.glitch.me/twitch-api/channels/",
    proms = index.map(d => fetch(url+d));

Promise.all(proms)
       .then(ps => Promise.all(ps.map(p => p.json()))) // p.json() also returns a promise
       .then(js => js.forEach((j,i) => (console.log(`RESPONSE FOR: ${index[i]}:`), console.log(j))));
.as-console-wrapper {
max-height: 100% !important;
}
like image 30
Redu Avatar answered Sep 19 '22 05:09

Redu