Can't get twitch tv stream to show online status

Can't get twitch tv stream to show online status
0.0 0

#1

I’m just about done with the project but I can’t get the page to display whether the channel is online or not. I think the problem may have to do with the getjson call in the middle of the other getjson call, but I don’t know any other way to do it. The stream information doesn’t appear to be in the first json call so I need to make another one, but when I do using the same strategy as the first, all the channels come back as undefined with null status on the stream. Thanks. Here is my javascript code. Sorry if the code is a little hard to read, codepen often formats the code oddly and I have trouble counteracting it.

$(document).ready(function() {
   
   

var url2 = " https://wind-bow.glitch.me/twitch-api/channels/";
var url3= "https://wind-bow.glitch.me/twitch-api/streams/";
var userNames = ["ESL_SC2", "OgamingSC2", "cretetion",  "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas","Freecodecamp"]
   for(var i = 0; i<userNames.length;i++){
           $.getJSON(url2+userNames[i],function(data){
         
         
            var onlineStatus;
            $.getJSON(url3+userNames[i],function(data2){
               if (data2.stream === null){onlineStatus="OFFLINE"}
               else{onlineStatus = "ONLINE"}
                 $('#channelInfo').prepend("<br><img src='"+data.logo+"' class = 'left' style=     'width:120px; border-radius:100%; bottom:100px;' > <br>");
       
                 $('#channelInfo').prepend("<ul class='center' style='font-size:50px;'>"+ "<a href ='"+data.url+"'>" + data.display_name +" </a>"+onlineStatus+ "</ul>");
         
                 if(data.status !== null){ $('#channelInfo').prepend("<ul class='right' style='font-size:20px;'>" + data.status +"</ul>" );
                                 }
                  $('#channelInfo').prepend("<hr>")
       
             });


         
      });
 }
});

And here is the link to the codepen


#2

$.getJSON is asynchronous, so the for loop does not stop and wait for any of the responses to come back before moving on to code which follows. What this means for you code is that the for loop finishes before the response can come back from your nested $.getJSON call, so the url created with the following line

$.getJSON(url3+userNames[i],function(data2){

ends up being:

$.getJSON('https://wind-bow.glitch.me/twitch-api/streams/undefined',function(data2){

The undefined shows up because after the for loop finishes, i = 8 and since there are only 8 elements in the userNames array, i = 8 would refer to a 9th element which does not exist.

Read about using the let key word instead of var to declare the variable i inside the for loop.


#3

Thanks Randelldawson! That simple change of var to let really fixed the problem. Interesting, I never would have expected such a simple change would have fixed the problem. I will definitely read more about the difference of let to var.


#4

It is really just a matter of global scope (var) vs block scope (let). The block scope that let creates allows i to “remember” it’s value at the time the call to the $.getJSON is made vs after the for loop has ended.


#5

It is definitely interesting seeing a situation where (var) screws up code while (let) allows it to run. I had another question. I have noticed that the links to the channels only work when I right-click (“open in new tab”). Is there some way to fix this? I have noticed the project that freecodecamp gave as an example has a similar problem as well. At least that is what is happening in my browser when I run their codepen.


#6

Codepen does not allow direct links, so you must put target="_blank" inside the anchor tag, so that a new window opens.


#7

Thanks again! I really appreciate it


#8

FYI - Before the let keyword was introduced in ES6, you had to use what is called an IIFE (Immediately Invoked Function Expression) to achieve the same kind of block scoping that let provides. For example, the following is your code rewritten using an IIFE.

$(document).ready(function() {
  var url2 = " https://wind-bow.glitch.me/twitch-api/channels/";
  var url3= "https://wind-bow.glitch.me/twitch-api/streams/";
  var userNames = ["ESL_SC2", "OgamingSC2", "cretetion",  "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas","Freecodecamp"]
  for(let i = 0; i<userNames.length;i++){
    (function(i) {
      $.getJSON(url2+userNames[i],function(data){
        var onlineStatus;
        $.getJSON(url3+userNames[i],function(data2){
          if (data2.stream === null){onlineStatus="OFFLINE"}
          else{onlineStatus = "ONLINE"}
          $('#channelInfo').prepend("<br><img src='"+data.logo+"' class = 'left' style=     'width:120px; border-radius:100%; bottom:100px;' > <br>");
          $('#channelInfo').prepend("<ul class='center' style='font-size:50px;'>"+ "<a href ='"+data.url+"' target=blank>" + data.display_name +" </a>"+onlineStatus+ "</ul>");
          if(data.status !== null){ $('#channelInfo').prepend("<ul class='right' style='font-size:20px;'>" + data.status +"</ul>" );}
          $('#channelInfo').prepend("<hr>")
        });
      });
    })(i);
  }
});

#9

Wow, definitely a bit more dense than what I had originally made. Do IIFE still have any value of using these days?


#10

They are still used in some code when needed. It is good to recognize it when you see it in older code. Check out the link below for a discussion on IIFE vs let.