Reputation: 58
I've got an array of names which I need to retrieve data from, and I'm currently doing this with $.getJSON inside a loop. It works and I can retrieve the data, but to output the correct value I need to use setTimeout or similar. I'm wondering if there's a more refined way of doing what I'm looking to achieve.
Here's what I've got.
var names = ["riotgames", "example"];
var online = [];
for (var i = 0; i < names.length; i++) {
$.getJSON('https://api.twitch.tv/kraken/streams/' + names[i], function(data) {
if (data.stream != null) {
online.push(data.stream.channel.display_name);
};
});
}
console.log(online) // outputs []
setTimeout(function() {
console.log(online) // outputs correctly
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Upvotes: 1
Views: 1652
Reputation: 227220
When doing $.getJSON
, you are triggering asynchronous requests. This means they run in the background. You do not wait for them to finish, their callbacks will trigger (like an event) once the request is done.
This means you cannot access online
from outside the callback(s).
If you want to "wait" for all the requests to finish, then I suggest using promises. You can use $.when
to combine all the requests into one promise then run a callback once everything is done.
var names = ["riotgames", "example"];
var promises = [];
for (var i = 0; i < names.length; i++) {
// $.getJSON returns a promise
promises.push($.getJSON('https://api.twitch.tv/kraken/streams/' + names[i]));
}
// Combine all promises
// and run a callback
$.when.apply($, promises).then(function(){
var online = [];
// This callback will be passed the result of each AJAX call as a parameter
for(var i = 0; i < arguments.length; i++){
// arguments[i][0] is needed because each argument
// is an array of 3 elements.
// The data, the status, and the jqXHR object
online.push(arguments[i][0].stream.channel.display_name);
}
console.log(online);
});
Upvotes: 4