$.getJSON, $.each and variable scope?

Ajax is asynchronous, anything that needs access to the viewers variable after it is populated needs to be inside of the complete callback of the ajax request.

Up vote 0 down vote favorite share g+ share fb share tw.

I've been looking through forums all day, but I'm not figuring it out. I'm calling the Justin. TV-API to display a list of my "followed" streams and then doing a nested call to check which one of them is online.

Here is the code I'm wanting to use: //Get Favorites as Object "favs" var viewers; $. GetJSON('api.justin.tv/api/user/favorites/hubschr..., function(favs) { $. Each(favs, function(key, value) { //For every Object, check if user is referenced in stream and therefore online $.

GetJSON('api.justin.tv/api/stream/list.json?chann... + favskey. Login + '&jsonp=? ', function(streams) { viewers = streams0.

Channel_count; }); $('#result'). Append(favskey. Title + ' ' + key + ': ' + favskey.

Login + ' (' + viewers + ') Viewers'); }); }); I then came across the problems with getJSON and asychronisation and rewrote my script a couple of times: first like this (replacing the $. Each): //Get Favorites as Object "favs" var viewers; $. GetJSON('api.justin.tv/api/user/favorites/hubschr..., function(favs) { for (var key in favs) { //For every Object, check if user is referenced in stream and therefore online $.

GetJSON('api.justin.tv/api/stream/list.json?chann... + favskey. Login + '&jsonp=? ', function(streams) { viewers = streams0.

Channel_count; }); $('#result'). Append(favskey. Title + ' ' + key + ': ' + favskey.

Login + ' (' + viewers + ') Viewers'); } }); then like this (replacing getJSON with non-asynchronus ajax): var favs; var streams; var viewers; $. Ajax({ url: 'api.justin.tv/api/user/favorites/hubschr..., async: false, dataType: 'json', success: function(favs) { for (var key in favs) { $. Ajax({ url: 'api.justin.tv/api/stream/list.json?chann... + favskey.

Login + '&jsonp=? ', async: false, dataType: 'json', success: function(streams) { viewers = streams0. Channel_count; } }); $('#result').

Append(favskey. Title + ': ' + favskey. Login + ' (' + viewers + ') Viewers'); } } }); In no cases I am able to pass the viewers-variable (which is written in the nested api-call to determine if the stream is online and how many viewers it has) to $('#result').

Append(favskey. Title + ': ' + favskey. Login + ' (' + viewers + ') Viewers'); My output is always undefined: Day9: day9tv (undefined) Viewers FollowGrubby: followgrubby (undefined) Viewers OneMoreGame.

TV: onemoregametv (undefined) Viewers I have done several checks with appends and alerts – the JSON-responses are valid. Who can help me out? Thank you very much for your time.

Jquery ajax variable-scope each getjson link|improve this question asked Mar 13 at 15:41Macks32.

Ajax is asynchronous, anything that needs access to the viewers variable after it is populated needs to be inside of the complete callback of the ajax request. Deferred objects would be the way to go here, i'll whip up a small demo. Update: jsfiddle.net/cMKkQ/ didn't need deferred objects, just restructured a little.

//Get Favorites as Object "favs" $. GetJSON('api.justin.tv/api/user/favorites/hubschr..., function(favs) { $. Each(favs, function(key, value) { //For every Object, check if user is referenced in stream and therefore online $.

GetJSON('api.justin.tv/api/stream/list.json?chann... + favskey. Login + '&jsonp=? ', function(streams) { $('#result').

Append(value. Title + ' ' + key + ': ' + value. Login + ' (' + streams0.

Channel_count + ') Viewers'); }); }); });? Update: Another way to do it: var favorites = ; function processFavorites () { $("#result").empty(); $. Each(favorites,function(index,obj){ // here we populate the results div $('#result').

Append(obj. Title + ' ' + index + ': ' + obj. Login + ' (' + obj.

Viewers + ') Viewers'); }); } function getFavorites () { favorites = ; $. GetJSON('api.justin.tv/api/user/favorites/hubschr..., function(favs) { var defArr = ; $. Each(favs, function(key, value) { //For every Object, check if user is referenced in stream and therefore online defArr.

Push($. GetJSON('api.justin.tv/api/stream/list.json?chann... + favskey. Login + '&jsonp=?

', function(streams) { favorites. Push({title:value. Title,key:key,login:value.

Login,viewers:streams0. Channel_count}); })); }); $.when. Apply($,defArr).

Always(function(){ processFavorites(); }); }); } // this runs the process of getting and processing favorites. Run it when you want. GetFavorites();?

However, the feeds are currently returning no results, I don't think it's related to this code. jsfiddle.net/cMKkQ/3.

1 Note to OP: The order that these are appended may not be predictable. All of the second getJSON calls will be fired off one after another and the responses may not arrive in the same order they were sent. – jfriend00 Mar 13 at 15:55 Thank you very much, this works perfectly.

I'll still try to get into deferred objects as I am interested in storing some data in variables to process later. Also so I can display them in a specific order. – Macks Mar 13 at 15:57 Okay, so I have to come back to this.

As I am trying to auto-update my list every few seconds and want to do some other stuff, I think that I should really be saving the list as a global variable. How can I achieve this? – Macks Mar 13 at 16:24 What do you need the global variable for?

If you need to update the list again, you need to make the ajax requests again. Just move this code into a function and run said function when you want it to update. – Kevin B Mar 13 at 18:02 What if I want to order the list or catch the streams that are favored but offline?

I just find it much more convenient to save it as a variable. Preferrably an array. I'll be experimenting with jQuery.when() and jxhr.push() – is that the right way to go?

– Macks Mar 13 at 19:19.

Related Questions