It's a Freecodecamp project (TwitchTV), which displayed several channels data including live stream, onlive, and all. Although I can have expected result (successfully display different channels data), I couldn't understand one issue (since it was not provided satisfied feedback on the community, so I post this question again in stackoverflow). Hopefully it could be answered well.
Here is my code:
var usernames = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp",
"storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "MedryBW"];
var html_all = "";
var html_live = "";
var html_offline = "";
$(document).ready(function() {
console.log("document ready");
getChannelData();
});
// get JSON data for channels profile
function getChannelData(i) {
for (var i = 0; i < usernames.length; i++)
{
$.ajax({
type: 'GET',
// url: 'https://api.twitch.tv/kraken/channels/twitch/',
url: 'https://wind-bow.glitch.me/twitch-api/channels/' + usernames[i],
error: function() {
console.log("error occurred when getting channel data");
},
success: function(data) {
displayData(data);
}
});
}
console.log("hi");
console.log(html_all);
button_click();
// $(".data").html(html_all); // no data displayed
}
/* function:
display the channels list
*/
function displayData(data){
var logo = "<img src="+data.logo+" target='_blank' />";
var name = " <span style='font-size:20px;'>" + data.display_name +"</span>";
var url = data.url;
var status = data.status;
var baseurl = "<a href=" + url + " target='_blank'>" + logo + name;
html_all += baseurl+"</a>"+"<br>";
$(".data").html(html_all);
console.log('test');
if (status != null) {
// live list
html_live += baseurl + "<p>" + status + "</p></a>" +"<br>";
}
else {
// offline list
html_offline += baseurl + "</a>" +"<br>";
}
}
/* function:
add click event to buttons
*/
function button_click(){
$("button.button-all").on("click", function() {
$(".data").html(html_all);
// console.log(html_all); // test
});
$("button.button-live").on("click", function() {
$(".data").html(html_live);
});
$("button.button-offline").on("click", function() {
$(".data").html(html_offline);
});
}
My question: in the defined getChannelData()
function, after the for()
loop, the statement console.log(html_all)
outputs ""
, empty. But the global variable html_all
is already updated after the for()
loop, why is empty in here. But then function button_click()
works as expected. If you open my source code in codepen, all button works fine. I don't understand, why variable html_all
's value can be accessed in button_click()
function if html_all
is still empty after for
loop? Does the callback function $.ajax({... success: function()
play a role?
I think the issue is that getChannelData
makes an AJAX call, which is asynchronous. If you put console.log(html_all)
inside of your success
callback, you should see what you expect.
Basically, as the document is loaded, your getChannelData
is called, but the AJAX request takes time to complete; in that time, the document continues to process your script, including the console.log(html_all)
. The AJAX call is completed and the html_all
variable is set, so the button_click()
and everything else will work, just after the console.log(html_all)
statement has finished.