[HELP] Problem with undefined variable during a for loop/AJAX cal

Hello Campers!

I am currently building out my Twitch API project and I ran into an issue while looping over an array to make AJAX calls.

I created an array of channel names that I want to make a query on. The array is named streamArray. The for loop works for the purpose of making the ajax call (url+streamArray[i]), but when I try to $.append the elements to the DOM streamArray[i] is undefined.

How do I make it so that the object of streamArray’s current iteration is defined?

Please refer to the JS section of my codepen below. The problem section is commented with ###FREE CODE CAMP QUESTION STARTS HERE.

Thanks so much :slight_smile:



If(ArielLeslie.coffee == true){
console.log("I summon you!")
} else{
for (let i = 0; i < streamArray.length; i++) {

Add the keyword let so i retains it’s value at the time the AJAX call is made. Otherwise, it will only have the last value of i which equal to 10 which is one more than the highest index in your your streamArray. That is why the undefined shows up.

Why is i 10? Because $.ajax is asynchronous and allows other code to run while it waits for a response. While the first AJAX call is being made, the for loop has already finished, so when the response comes back from the first and other AJAX calls, i is already at its final value of 10.

1 Like

Thank you so much!

A follow up question: I am a bit confused as to why “let” stores the value and “var” doesnt (if I leave it as i=0 doesn’t that mean var i=0?) .

I need to go re-read up on “let” again.

In this particular code, when you write i=0 in your for loop it has the same effect as writing var i = 0. The scope of i is within the $(‘document’).ready callback function.

Take a look at the let documentation and see if it helps you understand the concept of block scoping.

The var i declaration puts i in the global scope. In this case, the global scope is outside the $.ajax call. Since it $.ajax is asynchronous, it lets other sequential code keep running and then use the value of i (in the global scope) when the response comes back. The for loop has already finished, so i is something different than at the time the $.ajax call was originally made.

The let i creates a local scope for each iteration to use the new value of it and apply it to anything contained inside the for loop. The $.ajax call is made with the correct value of i, because it has been “locked in” during that particular iteration.

Before the keyword i was introduced in ES6, you had to use IIFEs (Immediately Invoked Function Expressions) to accomplish the same thing.