I am making a 'viewer' for Twitch TV, which shows if TV channels are online,offline or don't exist. I am using the API for Twitch TV. I have saved the channel names in an array, but when I try to append an array item to an HTML element, it shows 'undefined'. The array is a global variable.
My code is in this fiddle .
HTML:
<div class="container-fluid">
<div class="row row-centered">
<div class="col-md-4"></div>
<!-- This is a div containing divs for each channel -->
<div class="col-md-4 col-centered" id="displayHere">
</div>
<!-- The container div end here -->
<div class="col-md-4"></div>
</div>
</div>
My Javascript:
$(document).ready(function(){
streamsArr= ["ESl_SC2","OgamingSC2","cretetion","freecodecamp","storbeck","habathcx","RobotCaleb","noobs2ninjas","brunofin","comster404"];
for(var count=0;count<streamsArr.length;count++){
$.getJSON("https://api.twitch.tv/kraken/streams/"+streamsArr[count]+"?callback=?",function(data){
if(JSON.stringify(data.stream)=="null")
{
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+streamsArr[count]+"</span><span style=\"color:red;\">OFFLINE</span></div>");//shows 'undefined'
}
else if(data.hasOwnProperty("error"))
{
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+streamsArr[count]+"</span><span style=\"color:red;\">UNAVAILABLE</span></div>");//shows 'undefined'
}
else{
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+JSON.stringify(data.stream.channel.display_name)+"</span>"+JSON.stringify(data.stream.game)+"</div>");
}
});
}
});
Can someone tell me where the fault lies? Thanks.
由于JavaScript具有函数作用域,因此已为变量count
创建了一个闭包,这就是为什么count变量的值始终为10的原因。在ES6中,可以在for循环中使用let
而不是var
,因此count
可以在块范围内进行。
$.getJSON
method is asynchronous so For
loop may complete before current request returns a result. So value of the variable count
becomes 10.
Here is a fiddle that works https://jsfiddle.net/bkw5dLac/1/
$(document).ready(function(){ streamsArr= ["ESl_SC2","OgamingSC2","cretetion","freecodecamp","storbeck","habathcx","RobotCaleb","noobs2ninjas","brunofin","comster404"]; for(var count=0;count<streamsArr.length;count++){ getJSON(streamsArr[count]); } }); function getJSON(arr){ $.getJSON("https://api.twitch.tv/kraken/streams/"+arr+"?callback=?",function(data){ if(JSON.stringify(data.stream)=="null") { $("#displayHere").append("<div style=\\"padding:1%;\\"><span style=\\"font-size:1.3em;\\"> "+arr+"</span><span style=\\"color:red;\\">OFFLINE</span></div>");//shows 'undefined' } else if(data.hasOwnProperty("error")) { $("#displayHere").append("<div style=\\"padding:1%;\\"><span style=\\"font-size:1.3em;\\"> "+arr+"</span><span style=\\"color:red;\\">UNAVAILABLE</span></div>");//shows 'undefined' } else{ $("#displayHere").append("<div style=\\"padding:1%;\\"><span style=\\"font-size:1.3em;\\"> "+JSON.stringify(data.stream.channel.display_name)+"</span>"+JSON.stringify(data.stream.game)+"</div>"); } }); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container-fluid"> <div class="row row-centered"> <div class="col-md-4"></div> <!-- This is a div containing divs for each channel --> <div class="col-md-4 col-centered" id="displayHere"> </div> <!-- The container div end here --> <div class="col-md-4"></div> </div> </div>
Why OP's code not working as expected
1) Variable count
is a global variable to the anonymous callback function in $.getJSON
2) $.getJSON is asynchronous. So anonymous callback function is triggered only after the success of get request.
3) When the anonymous callback executes, value of count
will be modified in for loop. In many cases, it becomes 10. Because for loop completes execution before the callback is triggered
Why my fiddle is working
1) I have passed the value of streamArr
at count
to a local variable arr
.
2) Since, arr
is local variable to the function getJSON
, its value will not be modified in for loop. So anonymous callback function works as expected.
Let's try cleaning up the $.getJSON
function up a bit first:
var twitchAPI = "https://api.twitch.tv/kraken/streams/"+streamsArr[count]+"?callback=?"
and then encapsulate the success callback in a closure that has the index bound to it:
$.getJSON(twitchAPI, function(count) {
return function(data) {
if (JSON.stringify(data.stream) == "null") {
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + streamsArr[count] + "</span><span style=\"color:red;\">OFFLINE</span></div>");
} else if (data.hasOwnProperty("error")) {
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + streamsArr[count] + "</span><span style=\"color:red;\">UNAVAILABLE</span></div>");
} else {
$("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + JSON.stringify(data.stream.channel.display_name) + "</span>" + JSON.stringify(data.stream.game) + "</div>");
}
}
}(count));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.