Twitch API help

Twitch API help
0

#1

I’ve just about wrapped up my twitch API project but I have one big problem. Since I had to use two different APIs–one for the channel information and another for the streaming information, the channels and streaming info aren’t lining up properly. How can I fix this?

I’d prefer not to switch from JSON to Ajax if possible. Thanks!


#2

Hey @mbabaian, how are you?

So, I read your code. I think that you could approach this differently in two ways.

  • Try not to use append, or if you are using append, create a specific id for the elements you are creating. (you could use "id=" + userArray[i]) this will enable you to target that specific element later on and could use .html() instead of .append for the second call.
  • Another way to do it, is to nest both JSON calls (which essentially are AJAX calls). So you would only have one for loop with both calls.

A quick note. You are using two for loops, one with i and one with j. If the loops are not nested, you could use i for both, since the scope of the variable does not exit the loop. Use i then j when nesting. (what you are doing does not break anything, but I struggled with scope earlier on and would appreciate if someone had told me that).

Also, you can have only 1 <li> item per user and separate data inside the same <li> item.

If I didn’t explain myself please tell me so I can modify your code for better understanding.

Cheers!
Daniel S.


#3

Thank you for the thorough response. I wish I could say that I had success with your tips. I tried both ways you mentioned but I’m just not getting it…I can’t picture it in my head. Would you mind forking? I forked it and gave it a try. This is what happened:

http://codepen.io/mbabaian/full/LWeGGZ/

:confounded:

By the way, I originally tried .html() instead of .append() but only one result shows up at a time for me.

Anyway if you could fork and show me, I’d really appreciate it. This laptop is new and I really don’t want to throw it yet.


#4

Oooh @mbabaian , don’t throw it yet! You’ll need it.

Ok I started to fiddle around with the pen. I see the issue clearly now. The thing is, you are running the for loop and making all this calls right? But the loop goes super fast, and the calls take some time to come back, so which ever comes first, gets appended first. This issue becomes very common when using callbacks. You see, the callback function only executes until the data is ready. So the loop goes from i=0 to i=7 very quickly. And if the data of i=2 arrives first (for example), then that callback is executed.

The way you could solve this is nesting callbacks, but I don’t think it’s a good practice. Let me refactor your code and link it here.


#5

Ok, here’s the refactored code. Notice the function that protects the i.

for (var i = 0; i < userArray.length; i++) {
    (function(i){ //<-------- Protecting the i in this loop
      $.getJSON('https://wind-bow.gomix.me/twitch-api/channels/' + userArray[i] + '?callback=?', function(data) {
        if (data.display_name === undefined) {
          $("#channel-name").append("Channel not found");
        } else {
          event.preventDefault();
          $("#channel-logo").append('<li style="list-style:none"><img src="' + data.logo + '" alt="channel logo" /> </li>');
          $("#channel-name").append('<li style="list-style:none"> <a href="' + data.url + '"target="blank"> <span>' + data.display_name + '</span>' + '</a> </li>');
          $("#channel-status").append(`<li id='status_${userArray[i]}' style="list-style:none"></li>`); //Notice backticks instead of ''
        }
        // This is still inside the first getJSON, so it's the same i
        $.getJSON('https://wind-bow.gomix.me/twitch-api/streams/' + userArray[i] + '?callback=?', function(status) {
          if(status.stream === null) {
            $(`#status_${userArray[i]}`).html('Offline');
          } else {
            $(`#status_${userArray[i]}`).html('Online');
          }
        })
      });  
    })(i) // <-------------- Calling the protected i (it's a self calling function)
  }

I know it seems confusing, but it’s quite simple. If you would have console.log(i) on your first pen, you would get 8 eight times.

Link to pen: http://codepen.io/dsegovia90/pen/YZYqPv?editors=1010
Link to resource: http://stackoverflow.com/questions/15347750/getjson-and-for-loop-issue

Any questions please ask!

Notice if you fork and reload pen (by adding a space somewhere), the list seems to randomize each time. It’s not random, it’s the time each data takes to get back from the getJSON call. You can actually see this in the browser devTools on Network.

Cheers,
Daniel S.


#6

The problem you having is due to asynchronous nature of Ajax request. Meaning that the rest of the code, in this case loop iteration is processed before the request block.

I’m on my phone atm, so can’t really come up with many resources, but read up about asynchronous nature of Ajax and working with promises, it will make your life much easier and will make twitch project a breeze(I know it did for me).

Here is link to my app, I did it in angularjs but the concept is similar.

One point I need to add, it’s consider bad practice to create function within loop, in fact many tools will throw a warning. Try using $. forEach to iterate over array.


#7

Hi @sego90 Thank you for taking the time to work through this and explain it to me. If I understand correctly, you set aside the i and all its data in order to call it at the end of the program.When you use {} around userArray[i], is the array an object or a function? Yesterday I thought creating an object for each user in the array would’ve worked, but I got stuck when it came to actually creating the object.


#8

Thank you for the suggestions. Your pen is impressive. Why did you choose to use typescript instead of js? As for Angular, I noticed there’s a course on edX and I was thinking about taking it. Do you have any suggestions for resources on learning Angularjs? I’m not quite that far in my learning yet. :slight_smile:


#9

Hey mbabaian,

var hello = 'Hello';

console.log(`#{hello} world!`); // this is the same as
console.log(hello + ' world!'); //this, just another notation. 

It’s just a way to make code cleaner. It works great when inserting multiple variables in a string.


#10

Thank you, that’s very kind of you. I’ve chosen angularjs and typescript to challenge myself, I believe the best way to learn something is to use it. It was the first crack at both of them, so it was a fairly frustrating experience but worth it. angular is a framework with tons of potential and I bearly manage to scratch a surface. As for resources, I mainly use Pluralsight, it’s reasonably priced and with tons of practical courses, and of course good old youtube :slight_smile: Hang in there I hope your project turn up well. Once you get a hang of AJAX I will be a breeze.