Coded myself into a hole (Twitch Api Challenge) **Slightly lengthy read

Coded myself into a hole (Twitch Api Challenge) **Slightly lengthy read
0.0 0

#1

Hello all this will be the third post I’ve made about this challenge (even though it’s probably the second easiest challenge in the intermediate track oh well). I’m almost finished but I’ve hit a brick wall when it comes to getting online, offline, and all buttons to work. It seems the way I’ve designed the project I can’t use any variables to have the script determine which streams are online and offline and when to hide the div that contains the specific information. Code below with further explanations.

https://codepen.io/DebugAyem/pen/qXVvbW

$(document).ready(main);
function main() {
  
  var i;
  var currentStatus; //the status of the stream (name of stream)
  var check;  //variable that checks if stream exists
  var users = ["freecodecamp","ESL_SC2", "OgamingSC2", "cretetion"]; //twitch user array
  
users.forEach(function(userNames, i) {
  var twitchURL = "https://wind-bow.glitch.me/twitch-api/streams/" + userNames;

  $.getJSON(twitchURL, function(data) {
    
    console.log(data);
    
    $("#ch" + i).html("<h4 class='left'>" + userNames + "</h4>"); //inserts usernames into #ch id's
    
    check=data.stream; 
    
    
    if(check===null|| check===undefined){
      currentStatus = 'Offline'; //if var check shows stream doesn't exist set currentStatus to string 'offline'
    } else {
    currentStatus=check.channel.status;
    }
    
    $('#info'+ i).append('<p id="info"'+i+'>'+currentStatus+'</p>');
    $('#link'+ i).attr('href','https://www.twitch.tv/'+userNames);
  }); 
  
});
  
  $('#on').on('click',function (){
    //incomplete
    });
  
  $('#off').on('click',function (){
      //incomplete
  });
  
  $('#all').on('click',function (){
    $('.user'+i).show();
  });
  
  }

In looking at my code I believe my problems are this:

Due to my use of a .forEach loop at the beginning of my code I can’t (or don’t know how to) loop through the divs (in this case called user) to see which one to hide.

This is further compounded by the problem that the stream information is coming from an API (i.e “offline”) and I insert it into the html using Jquery so I’m not sure if I can even check for if the stream is active or not since the string ‘Offline’ isn’t technically part of my html.

One way I thought of fixing this was to try and hide all the offline streams from the get-go but that isn’t what the instructions say and frankly I’m not sure if I could even do that.

Any ideas for how I can get my buttons to hide or show the divs that contain the information based o their properties??


#2

I’ve edited your post for readability. When you enter a code block into the forum, remember to precede it with a line of three backticks and follow it with a line of three backticks to make easier to read. See this post to find the backtick on your keyboard.


#3

You can give each user a class the marks them on or offline as you first render each element. jQuery makes it easy to find and loop through the elements.


#4

Hmm ok but I don’t know which is going to be offline at any given moment since the info is being taken from the API so I can’t preprogram it. I have to get the info from the api and then post it to my html and then act based on that. Also what is the purpose of the (idx) in your pen? I keep seeing it when dealing with xmlrequests but I don’t know what it does. Thanks


#5

idx is just a parameter name, short for “index”. jQuery’s each method passes the index of the item you’re looking at as the first parameter to the callback function.

Just concern yourself with the data you get from your first AJAX call. When you get to building server-side applications, you can think about making an app that updates its data while the user’s on it. The code that I showed you isn’t affected by what’s on Twitch’s servers. It just manipulates the data stored in the client side of the app.


#6

I get what your code is doing but this marking of online v offline has to be done after the data from the API is printed on the html page and that’s my main dilemma. That and I’m not sure how to loop through the api information to know which classes to hide.

**Another idea that came to me is when I set currenStatus = ‘Offline’ I could give the specific user div that contains the span that has the information a class of offline or something but I still don’t know if the click function that I create later on will recognize this class generated by the script.
Man I hope ^ made some sense :frowning:


#7

What? No it doesn’t.

if(check===null|| check===undefined){ 
      // add offline users here
} else {
      // add online users here
}

#8

Oh well yes you’re right I worded that terribly, I just meant the data had to be accessed in general first (i.e check variable). So then I tried this

if(check===null|| check===undefined){
      currentStatus = 'Offline';
       off = $('.user'+i);
    } else {
    currentStatus=check.channel.status;
       on = $('.user'+i);
    }

and

$('#on').on('click',function (){
   off.hide();
    });
  
  $('#off').on('click',function (){
    on.hide();
  });
  
  $('#all').on('click',function (){
    $('.user'+i).show();
  });

but this seems to hide the divs at random. *Sigh


#9

I see the problem. You’ve hard-coded the HTML where the users will go. Let’s change that to make things easier.

Instead of these

<div class='user0'>
     <span id='ch0'></span>
     <a href='' target='_blank' id='link0'>
       <span id='info0'></span>
     </a>
   </div>
...
<div class='user3'>
     <span id='ch3'></span>
     <a href='' target='_blank' id='link3'>
      <span id='info3'></span>
     </a>
   </div>

Just have this

<ul id="streamers">
</ul>

Now in your JavaScript, we’ll change the code so that each user is added to the list. This is a much more dynamic and scalable strategy.

var $streamersList = $('#streamers'); //add this before you start looping through users

//...later

if(check===null|| check===undefined){ 
      // add offline users here
     $streamersList.append('<li class="offline">
       <h2>' + stream.channel.display_name + '</h2>
     </li>');
    // You can change this markup to display whatever data you want
} else {
      // add online users here
     // do the same thing here
}

This can get cleaner and easier to work with if we throw a template library like HandlebarsJS in the mix, but see if you can get this working the “hard” way first. I have an AJAX example where I use $.getJSON to access Github’s users API that uses the same strategy. You can take a look at it if you’d like:


#10

!!! Got it. Really appreciate the help man. Lot of quotation marks especially here

if(check===null|| check===undefined){
      currentStatus = 'Offline';
       $streamersList.append('<div class="off"><h1 class="user">'+userNames+'</h1><li class="offline"><a href="https://www.twitch.tv/'+userNames+'"target="_blank"><p>' + currentStatus + '</p></a></li></div>');
      
    } else {
    currentStatus=check.channel.status;
       $streamersList.append('<div class="on"><h1 class="user">'+userNames+'</h1><li class="online"><a href="https://www.twitch.tv/'+userNames+'"target="_blank"><p>' + currentStatus + '</p></a></li></div>');
      }

But it’s done. Here’s the new working codepen thanks. This was an all-day affair :smile: