0

I thought I got callbacks, but I can't get them to work in this little problem I set up to get my head around the concept :

I have a list of Twitch.tv streamers (I got sidetracked working on a freecodecamp problem) and an empty array :

var players = ["imaqtpie", "imaqtpie"]; //this guy's always online. It's just easier.
var games = [];

All I'm trying to do is to get the game played by each streamer and pass it to the "game" array on page load.

I have this :

var players = ["imaqtpie", "imaqtpie"];
var games = [];

function functionUNO(callback) {

    var a;

    for(i = 0; i < players.length; i++) {
      a = $.getJSON('https://wind-bow.gomix.me/twitch-api/streams/' + players[i] + '?&callback=?');
        games.push(a);
    };

    callback();

};

function functionDOS() {
    console.log(games);
};

$(document).ready(function(){

    functionUNO (function() {
        functionDOS();
    });

    });

which correctly returns the json in my array, but I can't figure out how to get only the game played.

I tried

var a = $.getJSON('https://wind-bow.gomix.me/twitch-api/streams/' + players[i] + '?&callback=?', function(json) {return json.stream.game});

which doesn't work, and

var a = $.getJSON('https://wind-bow.gomix.me/twitch-api/streams/' + players[i] + '?&callback=?', functionTRES);   

with a separate functionTRES

function functionTres(data) {
    games.push(data.stream.game);
}; 

which returns the game and the json...

What am I doing wrong?

2
  • I suspect this is another problem of return values and asynchronous requests. Commented Mar 25, 2017 at 17:24
  • Yep. Which is why I started dumbing down my problem to the very basic task of passing info from one array to another so I could identify what I was doing wrong. So far I can't figure it out. Commented Mar 25, 2017 at 17:30

2 Answers 2

1

You need to use jQuery.when(), as callback() should be excecuted once all promises are fulfilled. Since games is an array we need to use apply()

$.when.apply($, games).then(function() {
    callback();
});

instead of

callback();

Note: As per current code games is an arrau of promises.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem with your code is that you are pushing the promise a returned by $.getJSON(.. )

This needs to change so that instead of pushing that, you are listening for the return of the promise, and using the data contained in it. Since you are in a loop, you also have to wait for all of the promises to return, and even though this is not the best way to do it, all I did was leave a basic exit strategy for you to see what I mean.

Only then can you log what is in the games array. I've modified your code and added it below for you to see what I mean.

It's worth noting that the last iteration of the loop will not necessarily be the last promise being returned, as mentioned in the comments by @Christopher

A better approach, which is also mentioned in the answer by @Satpal, is to use a promise aggregator, such as $.when()

var players = ["imaqtpie", "imaqtpie"];
var games = [];

function functionUNO(callback) {

  var a;

  for (i = 0; i < players.length; i++) {
    $.getJSON('https://wind-bow.gomix.me/twitch-api/streams/' + players[i] + '?&callback=?').then(function(data) {
      games.push(data);
      if (i == players.length) {
        callback();
      }
    });

  };
};

function functionDOS() {
  console.log(games);
};

$(document).ready(function() {

  functionUNO(function() {
    functionDOS();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

2 Comments

The last item in the players array won't necessarily be the last promise to resolve. You could compre players.length with games.length but the arrays could still be in different orders. You would either have to create an object with the player as the key or use Satpal's approach and return the promises sequentially but then chain off it to get the data.
This seemed to work (if I changed "games.push(data)" to "games.push(data.stream.game)", however, the console was telling me that the code was running the functionDOS twice. As a matter of fact, putting the callback inside the for loop, without the if statement, returns exactly the same result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.