Hello fellow campers,
I have implemented callback functions in native JS (no jQuery, no async/wait
) triggered by the result of an API call via XMLHttpRequest()
.
Note that I am making 2 nested API calls: one to the old TwitchTV API (https://api.twitch.tv/kraken/channels/) and one to the new one (https://api.twitch.tv/kraken/streams/). I am doing these 2 nested calls for 3 TwitchTV channels successively (in a for
loop).
The calls are successful and I am able to extract the information I want… except that sometimes only 2, or only 1 or 0 calls are successful.
I have looked for a solution on the forum as well as the Internet, incl. Stack Overflow, but with no success.
I would really appreciate if someone had a clue
Thanks a mil,
Ed.
Code:
`
// TwitchTV blog https://blog.twitch.tv/client-id-required-for-kraken-api-calls-afbb8e95f843
// call the Twitch API for a channel
var clientID = "xxxxx";
var newTwitchTVAPI = "https://api.twitch.tv/kraken/streams/";
var oldTwitchTVAPI = "https://api.twitch.tv/kraken/channels/";
var twitchTVurl = "https://www.twitch.tv/"
var channelArr = [
"freecodecamp",
"noobs2ninjas",
"ESL_SC2"
];
var channelObjArr = [];
var twitchAPInew = [];
var twitchAPIv5 = [];
for (i = 0; i < channelArr.length; i++) {
// !! important: we need to build a function to localize i
// otherwise the asynchronous call will callback for the
// wrong i value.
(function (i) {
twitchAPIv5.push(new XMLHttpRequest());
twitchAPIv5[i].open("GET", oldTwitchTVAPI + channelArr[i]);
twitchAPIv5[i].setRequestHeader("Client-ID", clientID);
twitchAPIv5[i].send();
twitchAPInew.push(new XMLHttpRequest());
twitchAPInew[i].open("GET", newTwitchTVAPI + channelArr[i]);
twitchAPInew[i].setRequestHeader("Client-ID", clientID);
twitchAPInew[i].send();
// build an object for ever channel
channelObjArr.push(new Object());
channelObjArr[i].display_name = channelArr[i];
channelObjArr[i].url = twitchTVurl + channelArr[i];
// populate that objects with properties from the old API
twitchAPIv5[i].onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var temp0 = new Object();
temp0 = JSON.parse(this.response);
channelObjArr[i].logo = temp0.logo;
channelObjArr[i].description = temp0.status;
}
twitchAPInew[i].onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var temp1 = new Object();
temp1 = JSON.parse(this.response);
//create a channelObjArr[i] with properties from both twitchAPInew[i] and twitchAPIv5[i]
if (temp1.stream == null) {
channelObjArr[i].status = "offline";
}
else {
channelObjArr[i].id = temp1.stream._id;
channelObjArr[i].status = temp1.stream.stream_type;
channelObjArr[i].description = temp1.stream.channel.status;
channelObjArr[i].updated_at = temp1.stream.channel.updated_at;
channelObjArr[i].video_banner = temp1.stream.channel.video_banner;
}
console.log(channelObjArr[i]);
var htmlCode = "<div class='wrapper'>";
htmlCode += "<img class='logo' src='" + channelObjArr[i].logo + "' alt = 'channel logo' >";
htmlCode += "<div class='status' >" + channelObjArr[i].status + "</div>";
htmlCode += "<a href='" + channelObjArr[i].url + "'>" + "<div class = 'name-box' >" + channelObjArr[i].display_name + "</div></a>";
htmlCode += "<a href='" + channelObjArr[i].url + "'>" + "<div class='description-box'>" + channelObjArr[i].description + "</div></a>";
htmlCode += "</div>";
var d1 = document.getElementById('total-wrapper');
d1.insertAdjacentHTML('beforeend', htmlCode);
}
};
}
})(i);
};
</script>
`