Stuck with Twitch API challenge (JS part)

Hello, fellow campers!

I’m stuck with Javascript code for the challenge, here it is:

var users = ['ESL_SC2',
             'OgamingSC2',
             'cretetion',
             'freecodecamp',
             'storbeck',
             'habathcx',
             'RobotCaleb',
             'noobs2ninjas',
             'brunofin',
             'comster404'],
    baseURL = 'https://api.twitch.tv/kraken';

function getUsersInfo(_users, _URL) {
  var arr = [];
  _users.forEach(function(u) {
    var info = {};
    var getUsers = $.getJSON(_URL + '/users/' + u + '?callback=?');
    var getStreams = $.getJSON(_URL + '/streams/' + u + '?callback=?');
    getUsers.done(function(data) {
      info.name = data.display_name;
      data.logo === null ? info.logo = 'PLACEHOLDER' : info.logo = data.logo;
      info.url = 'https://twitch.tv/' + data.name;  
    });
    getStreams.done(function(data) {
      info.active = true;
      if (data.stream === null) {
        info.status = 'Offline';
      } else if (data.status === 422) {
        info.status = 'Offline';
        info.active = false;
      } else {
        info.status = "Online";
        info.game = data.stream.game;
        info.channel_status = data.stream.channel.status;
      };
    });
    arr.push(info);
  });
  return arr;
}

I’m trying to execute function getUsersInfo, assign the result to variable and then iterate over it like so:

var result = getUsersInfo(users, baseURL);
result.forEach(function(obj) {
  console.log(obj.name);
});

But it always return undefined. Looks like ajax response come after my function call and loop executes, so function return an array of empty objects. How to get around it?

What we have here is called a “race condition”. getUsersInfo() hasn’t completed by the time we get to the forEach loop. Anything you write outside of getUsersInfo() is probably going to complete before those promises ($.getJSON is a promise) have finished fetching data from the Twitch servers. This is a common point of confusion when campers get to the API projects. You’ll need to think about how you can handle each user’s info within that _users.forEach() loop rather than returning an array. I know, that isn’t a pure function, but this is life with async code for now (things get better with generators).

A couple of tips:

  • jQuery’s $.when() function is great for dealing with multiple promises.

      $.when(promise1, promise2).done(function(promise1Results, promise2Results){ 
          //Code here...
      })
    
  • You used a ternary for this line:
    data.logo === null ? info.logo = 'PLACEHOLDER' : info.logo = data.logo;
    …which is great! This should work just fine, but there’s a more common way to write these for variable assignments
    info.logo = data.logo === null? 'PLACEHOLDER' : data.logo;
    It gets better, though, because JavaScript is kind of like magic.
    info.logo = data.logo || 'PLACEHOLDER';

This part is always a struggle, but I’m sure you’ll get it. Hope this helps.

Wow. Thank you very much for the detailed answer, it helped me a lot!