2

I'm trying to use twitch.tv's api to get information about some channels. I have all the different channels im trying to get information about in an array which I iterate through with a forloop and within this loop I then make a $.ajax() for each one of these channels. After I get the information i want about these channels i store them in an object which i then push onto different arrays depending on wether or not the channel is currently streaming or offline. My issue seems to be that when I call the display method and change my divs html to the information about the channels, some of the requests have not completed yet and for this reason i dont get all the channels added onto the page. So my question is where should i call the display function in this code and if there is a better approach to what im trying to achieve. Thanks in advance here is the code. https://jsfiddle.net/bwsvxsdv/4/

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.min.js"></script>
    </head>
<body>
    <div class="well">
        <h1>Twitch.TV API</h1>

    </div>

    <div class="row">
        <div class="col-sm-3 text-center">
            Name
        </div>

        <div class="col-sm-9 text-center">
            Status
        </div>
    </div>

    <div class="channelContainer">

    </div>
    <script>
        $streamers = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp",
        "storbeck", "habathcx", "RobotCaleb",
        "noobs2ninjas", "brunofin", "comster404","zxcxxxxzzxxxxc"];

        $onlineChannels = [];
        $offlineChannels = [];
        $closedChannels = [];
        $nonExistantChannels = [];

        function getStreamInfo(callback){
            for($i=0;$i<$streamers.length;$i++){
                $.ajax({
                    name:$streamers[$i],
                    length:$streamers.length-1,
                    index:$i,
                    func: callback,
                    url:'https://api.twitch.tv/kraken/streams/'+$streamers[$i],
                    dataType:'JSON',
                    success: function(data){

                        if(data.stream != null){//if there is stream information
                            //add to online channels
                            //console.log("its a streaming channel");
                            $chanInfo = {"name":this.name,"game":data.stream.game,"status":data.stream.channel.status};
                            $onlineChannels.push($chanInfo);
                        }else{
                            //add to offlineChannels
                            //console.log("currently not streaming");
                            $chanInfo = {"name":this.name,"status":"Offline"};
                            $offlineChannels.push($chanInfo);
                        }



                    },
                    error: function(data){
                        if(data.status === 422){
                            //console.log('add to closedChannels');
                            $chanInfo = {"name":this.name,"status":"Account closed"};
                            $closedChannels.push($chanInfo);
                        }

                        if(data.status === 404){
                            //console.log('add to nonExistantChannels');
                            $chanInfo = {"name":this.name,"status":"Non existant channel"};
                            $nonExistantChannels.push($chanInfo);
                        }
                    },//end of error                        
                    complete: function(){
                        if(this.index === this.length){
                            callback();
                        }
                    }
                });//end of ajax request

            }//end of for loop
        }//end of function

        function displayChannels(){
        console.log('doing displayChannels function');
        $chans = [$onlineChannels,$offlineChannels,$closedChannels];

        $html = "";
        for($i =0;$i<$onlineChannels.length;$i++){
            console.log("making the html");
            $html+= '<div class="row"><div class="col-sm-3 text-center">'+$onlineChannels[$i]["name"]+'</div><div class="col-sm-9 text-center">'+$onlineChannels[$i]["status"]+'</div></div>'

        }
        for($i =0;$i<$offlineChannels.length;$i++){
            console.log("making the html");
            $html+= '<div class="row"><div class="col-sm-3 text-center">'+$offlineChannels[$i]["name"]+'</div><div class="col-sm-9 text-center">'+$offlineChannels[$i]["status"]+'</div></div>'

        }
        for($i =0;$i<$closedChannels.length;$i++){
            console.log("making the html");
            $html+= '<div class="row"><div class="col-sm-3 text-center">'+$closedChannels[$i]["name"]+'</div><div class="col-sm-9 text-center">'+$closedChannels[$i]["status"]+'</div></div>'

        }
        console.log($html);
        console.log("about to add html");
        $(".channelContainer").html($html);
        console.log("html added");
        }

        getStreamInfo(displayChannels);
    </script>
</body>

mjmendes
  • 89
  • 9
  • What is name:$streamers[$i], length:$streamers.length-1, index:$i, func: callback, in the ajax ? Beside in every loop you are using $i . Do you want $i to be a global variable? – brk Jun 02 '16 at 04:08
  • @user2181397 That is just the name of the streamer that im currently busy with im using a for loop to go through all the different streamers – mjmendes Jun 02 '16 at 04:11
  • what ajax properties are these `name: $streamers[$i], length: $streamers.length - 1, index: $i, `? – madalinivascu Jun 02 '16 at 04:15
  • @madalinivascu Those were variables i wanted to use within my success or error function i didnt know how else to access them if not like this – mjmendes Jun 02 '16 at 04:18
  • you don't need them there lol – madalinivascu Jun 02 '16 at 04:23

3 Answers3

2

You can use Deferred array like so and call your callback when all the deferred objects have been resolved.

$streamers = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp",
  "storbeck", "habathcx", "RobotCaleb",
  "noobs2ninjas", "brunofin", "comster404", "zxcxxxxzzxxxxc"
];

$onlineChannels = [];
$offlineChannels = [];
$closedChannels = [];
$nonExistantChannels = [];

function getStreamInfo() {
    var deferred = [];   // deferred array.
    for ($i = 0; $i < $streamers.length; $i++) {
      deferred.push(
        $.ajax({
          name: $streamers[$i],
          length: $streamers.length - 1,
          index: $i,

          url: 'https://api.twitch.tv/kraken/streams/' + $streamers[$i],
          dataType: 'JSON',
          success: function(data) {

            if (data.stream != null) { //if there is stream information
              //add to online channels
              //console.log("its a streaming channel");
              $chanInfo = {
                "name": this.name,
                "game": data.stream.game,
                "status": data.stream.channel.status
              };
              $onlineChannels.push($chanInfo);
            } else {
              //add to offlineChannels
              //console.log("currently not streaming");
              $chanInfo = {
                "name": this.name,
                "status": "Offline"
              };
              $offlineChannels.push($chanInfo);
            }



          },
          error: function(data) {
              if (data.status === 422) {
                //console.log('add to closedChannels');
                $chanInfo = {
                  "name": this.name,
                  "status": "Account closed"
                };
                $closedChannels.push($chanInfo);
              }

              if (data.status === 404) {
                //console.log('add to nonExistantChannels');
                $chanInfo = {
                  "name": this.name,
                  "status": "Non existant channel"
                };
                $nonExistantChannels.push($chanInfo);
              }
            } //end of error      

        }) //end of ajax request
      );





    } //end of for loop
    return deferred; // return the array
  } //end of function

function displayChannels() {
  console.log('doing displayChannels function');
  $chans = [$onlineChannels, $offlineChannels, $closedChannels];

  $html = "";
  for ($i = 0; $i < $onlineChannels.length; $i++) {
    console.log("making the html");
    $html += '<div class="row"><div class="col-sm-3 text-center">' + $onlineChannels[$i]["name"] + '</div><div class="col-sm-9 text-center">' + $onlineChannels[$i]["status"] + '</div></div>'

  }
  for ($i = 0; $i < $offlineChannels.length; $i++) {
    console.log("making the html");
    $html += '<div class="row"><div class="col-sm-3 text-center">' + $offlineChannels[$i]["name"] + '</div><div class="col-sm-9 text-center">' + $offlineChannels[$i]["status"] + '</div></div>'

  }
  for ($i = 0; $i < $closedChannels.length; $i++) {
    console.log("making the html");
    $html += '<div class="row"><div class="col-sm-3 text-center">' + $closedChannels[$i]["name"] + '</div><div class="col-sm-9 text-center">' + $closedChannels[$i]["status"] + '</div></div>'

  }
  console.log($html);
  console.log("about to add html");
  $(".channelContainer").html($html);
  console.log("html added");
}


var deferredArr = getStreamInfo();
// call your callback once all the ajax calls are done
$.when.apply(null, deferredArr).done(function() {
  alert("All requests completed!. Now calling displayChannels");
  displayChannels();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="well">
  <h1>Twitch.TV API</h1>

</div>

<div class="row">
  <div class="col-sm-3 text-center">
    Name
  </div>

  <div class="col-sm-9 text-center">
    Status
  </div>
</div>

<div class="channelContainer">

</div>
Sandeep Nayak
  • 4,649
  • 1
  • 22
  • 33
0
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four ajax requests resolve.
// a1, a2, a3 and a4 are lists of length 3 containing the response text,
// status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
// NOTE:  This function must return the value 
//        from calling the $.ajax() method.
return $.ajax({
    url: "someUrl",
    dataType: "json",
    data:  yourJsonData,            
    ...
});
}

use $.when functionality supported bu jquery

it is working like promise.

hope this will work for you.

Punit
  • 450
  • 3
  • 11
0

I have go through the code and It seems fine except the calling approach.In your approach the some of request information is not with you when the DIV is loaded.

Solution : Call the display method after call and get all information from the API.To do it you can use "Multiple simultaneous ajax requests in on callback" as follows

code skeleton

make your API calls happens inside the "when block" and then after complete all then you can call the display method to populate your data into the view layer

Thank you.

Nuwa
  • 461
  • 4
  • 10