Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript JSON for each with array of feeds

In my example I am trying to fetch the ID and Description from each feed listed in my array feedUrls, but the order of how each feed is fetched doesn't match.

As shown below the result is not from first to last feed in my array, although they the feeds are listed in the array feedUrls from 001 to 005.

var feedUrls = ["https://api.myjson.com/bins/nkvdl", "https://api.myjson.com/bins/13wd2h", "https://api.myjson.com/bins/1b1kbt", "https://api.myjson.com/bins/10zc7d", "https://api.myjson.com/bins/60sqx"];

var arrayData1 = [];
var arrayData2 = [];

var getJSON = function(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'json';
  xhr.onload = function() {
    var status = xhr.status;
    if (status === 200) {
      callback(null, xhr.response);
    } else {
      callback(status, xhr.response);
    }
  };
  xhr.send();
};

feedUrls.forEach(function(entry) {
getJSON(entry,
  function(err, data) {
    if (err !== null) {
      alert('Something went wrong: ' + err);
    } else {
      try {
        arrayData1.push("<li>" + data[0].id + "</li>");
      } catch (e) {}
      document.getElementById('listId1').innerHTML = arrayData1.join("");
    }
  });
});

feedUrls.forEach(function(entry) {
getJSON(entry,
  function(err, data) {
    if (err !== null) {
      alert('Something went wrong: ' + err);
    } else {
      try {
        arrayData2.push("<li>" + data[0].title + "</li>");
      } catch (e) {}
			document.getElementById('listId2').innerHTML = arrayData2.join("");
    }
  });
});
ul {
display: inline-block;
}
<ul id="listId1">empty</ul>
<ul id="listId2">empty</ul>

Result:

001
005
004
003
002
title 001
title 004
title 002
title 005
title 003

Expected:

001
002
003
004
005
title 001
title 002
title 003
title 004
title 005 
like image 552
Joe Berg Avatar asked Apr 23 '26 03:04

Joe Berg


1 Answers

forEach() provides an index to the callback, which you can use in order to collect the results in their expected order, something like

var feedUrls = ["https://api.myjson.com/bins/nkvdl", "https://api.myjson.com/bins/13wd2h", "https://api.myjson.com/bins/1b1kbt", "https://api.myjson.com/bins/10zc7d", "https://api.myjson.com/bins/60sqx"];

var arrayData1 = [];
var arrayData2 = [];

var getJSON = function(url, callback, index) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'json';
  xhr.onload = function() {
    var status = xhr.status;
    if (status === 200) {
      callback(null, xhr.response, index);
    } else {
      callback(status, xhr.response, index);
    }
  };
  xhr.send();
};

feedUrls.forEach(function(entry, index) {
getJSON(entry,
  function(err, data, index) {
    if (err !== null) {
      alert('Something went wrong: ' + err);
    } else {
      try {
        arrayData1[index]="<li>" + data[0].id + "</li>";
      } catch (e) {}
      document.getElementById('listId1').innerHTML = arrayData1.join("");
    }
  },index);
});

feedUrls.forEach(function(entry, index) {
getJSON(entry,
  function(err, data) {
    if (err !== null) {
      alert('Something went wrong: ' + err);
    } else {
      try {
        arrayData2[index]="<li>" + data[0].title + "</li>";
      } catch (e) {}
			document.getElementById('listId2').innerHTML = arrayData2.join("");
    }
  },index);
});
ul {
display: inline-block;
}
<ul id="listId1">empty</ul>
<ul id="listId2">empty</ul>

The new part is the index variable.

Otherwise what the comment says: you have a number of independent XHR-s, the order of their completion has no guarantees.

like image 194
tevemadar Avatar answered Apr 24 '26 16:04

tevemadar