Stuck with Twitch API challenge (JS part)

Stuck with Twitch API challenge (JS part)
0

#1

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?


#2

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.


#3

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