Variable isn't changing in for loop - JavaScript - javascript

Why is this outputting each feedName as the same name (MedryBW)? I've spent a while messing around with it, can't figure it out. I want it to output the name of the feed in each iteration of the loop rather than repeating the same one over and over again. Thanks everyone.
var feeds = ["Towellie", "TrumpSC", "TeamSp00ky", "TwitchPlaysPokemon", "Widgitybear", "AriaBlarg", "TheMexicanRunner", "OPNerd", "rabbitbong", "Wingsofdeath", "MedryBW"];
$(document).ready(function(){
for(x = 0; x < feeds.length; x++){
var feedName = feeds[x];
$.getJSON('https://api.twitch.tv/kraken/streams/' + feeds[x] + '?callback=?', function(data) {
if(data.stream === null){
$('#feeds').append("<p>" + feedName + " is offline </p>");
} else {
$('#feeds').append("<p>" + feedName + " is streaming " (data.stream.game) + "/<p>");
}
});
}
});

Because callback function runs much later, not in the loop, and it just gets variable value after loop has finished (last value), use bind function to pass variable to the function
var feeds = ["Towellie", "TrumpSC", "TeamSp00ky", "TwitchPlaysPokemon", "Widgitybear", "AriaBlarg", "TheMexicanRunner", "OPNerd", "rabbitbong", "Wingsofdeath", "MedryBW"];
$(document).ready(function() {
for(x = 0; x < feeds.length; x++){
var feedName = feeds[x];
$.getJSON('https://api.twitch.tv/kraken/streams/' + feeds[x] + '?callback=?', function(feedName, data) {
if (data.stream === null) {
$('#feeds').append("<p>" + feedName + " is offline </p>");
}else{
$('#feeds').append("<p>" + feedName + " is streaming " + (data.stream.game) + "/<p>");
}
}.bind(this, feedName));
}
});

As you have written Ajax in for loop , The success callback executes after for loop has executed
var feeds = ["Towellie", "TrumpSC", "TeamSp00ky", "TwitchPlaysPokemon", "Widgitybear", "AriaBlarg", "TheMexicanRunner", "OPNerd", "rabbitbong", "Wingsofdeath", "MedryBW"];
$(document).ready(function() {
feeds.forEach(function(feedName) {
$.getJSON('https://api.twitch.tv/kraken/streams/' + feedName + '?callback=?', function(data) {
if (data.stream === null) {
$('#feeds').append("<p>" + feedName + " is offline </p>");
} else {
$('#feeds').append("<p>" + feedName + " is streaming " + (data.stream.game) + "/<p>");
}
});
});
})
THe Above change will work

You can achieve this by.
var feeds = ["Towellie", "TrumpSC", "TeamSp00ky", "TwitchPlaysPokemon", "Widgitybear", "AriaBlarg", "TheMexicanRunner", "OPNerd", "rabbitbong", "Wingsofdeath", "MedryBW"];
$(document).ready(function(){
var divText;
for(x = 0; x < feeds.length; x++){
var feedName = feeds[x];
$.getJSON('https://api.twitch.tv/kraken/streams/' + feeds[x] + '?callback=?', function(data) {
if(data.stream === null){
divText = divText + '<p>'+feedName+' is offline </p>';
}else{
divText = divText + '<p>'+feedName+' is streaming '+(data.stream.game) +'</p>'
}
});
}
$('#feeds').append(divText);
//or $('#feeds').html(divText);
})

Related

Google Books API shows only 10 results. Want to iterate the startIndex so that it loops until all the results are shown

function bookSearch() {
var search = document.getElementById('search').value
document.getElementById('results').innerHTML = ""
console.log(search)
var startIndex =
So I want to iterate the ajax call until it shows all the items and not just the 10. Can get 40 by using maxresults parameter. So the startIndex needs to change from 0 to 20 to 40 to 60 and so on after every iteration.
while (startIndex < 2000) {
$.ajax({
url: "https://www.googleapis.com/books/v1/volumes?q=" + search + "&startIndex=" + startIndex + "&maxResults=40",
dataType: "json",
success: function (data) {
console.log(data)
for (i = 0; i < data.items.length; i++) {
results.innerHTML += "<h2>" + data.items[i].volumeInfo.title + "</h2>"
results.innerHTML += "<h2>" + data.items[i].volumeInfo.authors + "</h2>"
results.innerHTML += "<h2>" + data.items[i].volumeInfo.publishedDate + "</h2>"
}
},
type: 'GET'
});
}
}
document.getElementById('button').addEventListener('click', bookSearch, false)
You can try this. Count total_items until it reach more than 40 and loop the function to print the results:
// start
var startIndex=0;
// button clicked
$("#button").click(function(){
$("#results").html('<img src="img/loader.gif" alt="" class="loader">');
var searchInput = $("#search").val();
getBooks(searchInput)
})
// onclick function run
function getBooks(search) {
RunApi(search, startIndex);
$("#results img").remove();
}
// run function to get results if available
function RunApi(search, start){
$.ajax({
url:"https://www.googleapis.com/books/v1/volumes?q=" + search + "&maxResults=40&startIndex="+start,
dataType: "json",
success: function(data) {
console.log(data)
totalItems = data.totalItems;
if(data.items){
for(i=0; i<data.items.length; i++){
if(data.items[i].volumeInfo){
var itemNubmer = startIndex+i;
results.innerHTML += "<h2>"+itemNubmer+": " + data.items[i].volumeInfo.title + "</h2>"
// results.innerHTML += "<h2>" + data.items[i].volumeInfo.authors + "</h2>"
// results.innerHTML += "<h2>" + data.items[i].volumeInfo.publishedDate + "</h2>"
}
}
}
// repeat the function
if(totalItems > 40){
startIndex+=40;
RunApi(search, startIndex);
}
},
type:'GET'
});
}

Problem when loop a function that calls several JSONs several times

I have a function (selectWord ()) that collects selected words, which calls a function (view (word [i])) by passing each word through a loop.
selectWord():
$('#button').on('click', function() {
var text = "";
var lang = $("#lang").text();
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
var word = text.split(" ");
$('#load').html("");
var promises = [];
for (var i = 0; i < word.length; i++) {
promises.push(Promise.resolve(view(word[i], lang)));
}
Promise.all(promises).catch(function(err) {
console.log("error");
return err;
}).then(function() {
$.each(promises, function(key, val) {
$.each(val, function(k, v) {
console.log("promises " + k + " " + v + " " + v[k] + '<br>');
$('#div').append("promises " + k + " " + v + " " + v[k] + '<br>');
});
});
});
}
});
view():
function view(word, lang) {
var html = "";
var id = "";
img = "";
ids = [];
fullLemmas = [];
gramCats = [];
setTimeout(wiki(word, lang), 1000);
setTimeout(function() {
for (var i = 0; i < ids.length; ++i) {
if (i == 0) {
getImg(ids[i], word);
wiki = fullLemmas[i];
gramCategory = gramCats[i];
}
}
}, 2000);
setTimeout(function() {
for (var i = 0; i < ids.length; ++i) {
if (i == 0) {
id = ids[i];
html += '<li class="col-12 col-md-6 col-lg-3"><div class="cnt-block equal-hight" style="height: 349px;"><figure><img id ="' + id + '" src="' + img + '" class="img-responsive" alt=""></figure><h3>"' + word + ' (' + gramCats[i] + ')' + '"</h3>';
}
html += '<p>' + fullLemmas[i] + ' (' + gramCats[i] + ')</p>';
}
html += '</li>';
return html;
}, 3000);
}
The view function in turn calls two functions that run through a JSON with getJSON (), the problem is synchrony. I have used setTimeOut () and Promises but I do not understand what it returns.
When showing the words, it keeps only the data of the last word.

json call does'nt update in IE 10

I use this tiny script to feed a playlist and updates it every 20 sec. - for some reason it does'nt update in ie10 (and older versions too, I guess) - I failed to see where it goes wrong, any ideas...?
function playlist() {
$.getJSON("/playlist/", function (data) {
$("#play-now-arti").empty();
$("#play-now-title").empty();
$("#last-played").empty();
var i = 0;
$.each(data.PlayHistory.PlayInfo, function (index, value) {
var arti = value["ARTI"];
var title = value["TITLE"];
i++;
if (i == 1) {
$("#now-playing-artist").html(arti);
$("#now-playing-song").html(title);
}
else if (i > 1 && i < 8) {
$("<li>" + arti + " - <span>" + title + "</span></li>").appendTo("#last-played");
}
});
});
setTimeout(playlist, 20000);
};
playlist();
It was caching, indeed... - by adding "$.ajaxSetup({ cache: false });" to my function IE now updates just like the other browsers...
function playlist() {
$.ajaxSetup({ cache: false });
$.getJSON("/playlist/", function (data) {
$("#playlist").empty();
var i = 0;
$.each(data.PlayHistory.PlayInfo, function (index, value) {
var arti = value["ARTI"];
var title = value["TITLE"];
var spotify = value["Spotify"];
i++;
if (i == 1) {
$("<li class=\"jp-playlist-current\"><div tabindex=\"0\" class=\"jp-playlist-item jp-playlist-current\"><span class=\"jp-artist\">" + arti + ":</span><img src=\"/img/spotify.png\" style=\"border: 0;\" /><br><span class=\"jp-title\">" + title + "</span></div></li>").appendTo("#playlist");
}
else {
$("<li><div tabindex=\"0\" class=\"jp-playlist-item\"><span class=\"jp-artist\">" + arti + ":</span><img src=\"/img/spotify.png\" style=\"border: 0;\" /><br><span class=\"jp-title\">" + title + "</span></div></li>").appendTo("#playlist");
}
});
});
setTimeout(playlist, 200000);
};
playlist();

CRM Javascript, multiple independent sets of script on the same OnLoad form

I am new to Javascript, I basically have a form to edit on CRM. I have two pieces of script, independent of each other, they both work fine on their own when I use the OnLoad feature, however when I put both sets of code into the same script developer (since its for the same form on CRM), one of them does not work.
Can anyone help and is there any special syntax to have multiple scripts on the same form?
Thanks
The Javascript is below:
var _roles = 'Compliance'; //array of security roles name
var _fields = 'new_pend'; // array of field schema names to enable
UpdateFields();
/* Functions */
function UpdateFields() {
var oXml = GetCurrentUserRoles();
if (oXml != null) {
var roles = oXml.selectNodes("//BusinessEntity/q1:name");
if (roles != null) {
for (i = 0; i < roles.length; i++) {
for (j = 0; j < _roles.length; j++) {
if (roles[i].text == _roles[j]) {
for (k = 0; k < _fields.length; k++) {
try {
document.getElementById(_fields[k]).Disabled = false;
} catch (e) {
}
}
return;
}
}
}
}
}
return;
}
function GetCurrentUserRoles() {
var xml = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
GenerateAuthenticationHeader() +
" <soap:Body>" +
" <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>role</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>name</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>roleid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>role</q1:LinkFromEntityName>" +
" <q1:LinkToEntityName>systemuserroles</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>roleid</q1:LinkToAttributeName>" +
" <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>systemuserid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>systemuserroles</q1:LinkFromEntityName>" +
" <q1:LinkToEntityName>systemuser</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>systemuserid</q1:LinkToAttributeName>" +
" <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkCriteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>systemuserid</q1:AttributeName>" +
" <q1:Operator>EqualUserId</q1:Operator>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:LinkCriteria>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction", " http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
return (resultXml);
}
Hi everyone who has read this, I found a solution to the problem.
I used an If statement to define what the output should be based on an input into the function. This is shown in the code below, Use this code with the function GetCurrentUserRoles. Thanks for all the help.
if(UserHasRole("Collections") ==true)
{
crmForm.all.new_pend.Disabled = false;
return;
}
else if (UserHasRole("Collections") ==false)
{
crmForm.all.new_pend.Disabled = true;
return;
}
function UserHasRole(roleName)
{
//get Current User Roles, oXml is an object
var oXml = GetCurrentUserRoles();
if(oXml != null)
{
//select the node text
var roles = oXml.selectNodes("//BusinessEntity/q1:name");
if(roles != null)
{
for( i = 0; i < roles.length; i++)
{
if(roles[i].text == roleName)
{
//return true if user has this role
return true;
}
}
}
}
//otherwise return false
return false;
}

Code only works if I alert out before the code that's bombing out?

This is just freakin weird to me. So if I don't
function BindAlbumAndPhotoData()
{
// Get an array of all the user's Albums
var aAlbums = GetAllAlbums(userID, token);
alert("aAlbums: " + aAlbums);
if (aAlbums == null || aAlbums == "undefined")
return;
// Set the default albumID
var defaultAlbumID = aAlbums[0].id;
};
So I get an undefined error on the line var defaultAlbumID = aAlbums[0].id; if I don't uncomment the alert("aAlbums: " + aAlbums);
what the heck? If I comment out alert("aAlbums: " + aAlbums); then I get an undefined for the var defaultAlbumID = aAlbums[0].id;
This is so weird. I've been working all night to figure out why I kept getting an undefined for the aAlbum[0] and as soon as I add back an alert that I used to have above it, all is fine...makes no sense to me.
Here's the full code of GetAllAlbums:
function GetAllAlbums(userID, accessToken)
{
var aAlbums = []; // array
var uri = "/" + userID + "/albums?access_token=" + accessToken;
alert("uri: " + uri);
FB.api(uri, function (response)
{
// check for a valid response
if (!response || response.error)
{
alert("error occured");
return;
}
for (var i = 0, l = response.data.length; i < l; i++)
{
alert("Album #: " + i + "\r\n" +
"response.data[i].id: " + response.data[i].id + "\r\n" +
"response.data[i].name: " + response.data[i].name + "\r\n" +
"response.data[i].count: " + response.data[i].count + "\r\n" +
"response.data[i].link: " + response.data[i].link
);
aAlbums[i] = new Album(
response.data[i].id,
response.data[i].name,
response.data[i].count,
response.data[i].link
);
alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
}
});
return aAlbums;
}
so I'm not returning the array until I hit the callback of the FB.api async call so I don't see how my defaultAlbumID = aAlbums[0].id; line of code is executing before I have a valid array of data back. When I put in the alert, ovbvioulsly it's delaying before it hits my line defaultAlbumID = aAlbums[0].id; causing it to I guess luckily have data beacuse the async FB.api call is done but again I don't see how that's even possible to have an issue like this when I'm waiting for the call before proceeding on and returning the array to aAlbums in my BindAlbumAndPhotoData() method.
UPDATE #3
function BindAlbumAndPhotoData()
{
GetAllAlbums(userID, accessToken, function (aAlbums)
{
alert("we're back and should have data");
if (aAlbums === null || aAlbums === undefined) {
alert("array is empty");
return false;
}
var defaultAlbumID = aAlbums[0].id;
// Set the default albumID
var defaultAlbumID = aAlbums[0].id;
// Bind the album dropdown
alert(" defaultAlbumID: " + defaultAlbumID);
});
};
function GetAllAlbums(userID, accessToken, callbackFunctionSuccess)
{
var aAlbums = []; // array
var uri = "/" + userID + "/albums?access_token=" + accessToken;
FB.api(uri, function (response)
{
// check for a valid response
if (!response || response.error)
{
alert("error occured");
return;
}
for (var i = 0, l = response.data.length; i < l; i++)
{
alert("Album #: " + i + "\r\n" +
"response.data[i].id: " + response.data[i].id + "\r\n" +
"response.data[i].name: " + response.data[i].name + "\r\n" +
"response.data[i].count: " + response.data[i].count + "\r\n" +
"response.data[i].link: " + response.data[i].link
);
aAlbums[i] = new Album(
response.data[i].id,
response.data[i].name,
response.data[i].count,
response.data[i].link
);
alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
}
// pass the array back to the callback function sent as a param to the GetAllAlbums method here
callbackFunctionSuccess(aAlbums);
});
}
It's not hitting my alert in the callback. I must still be doing something wrong here.
UPDATE #4 - for some reason it's not hitting my FB.api callback now.
function GetAllAlbums(userID, accessToken, callbackFunctionSuccess)
{
var aAlbums = []; // array
var uri = "/" + userID + "/albums?access_token=" + accessToken;
alert("uri: " + uri);
FB.api(uri, function (response)
{
// check for a valid response
if (!response || response.error)
{
alert("error occured");
return;
}
for (var i = 0, l = response.data.length; i < l; i++) {
alert("Album #: " + i + "\r\n" +
"response.data[i].id: " + response.data[i].id + "\r\n" +
"response.data[i].name: " + response.data[i].name + "\r\n" +
"response.data[i].count: " + response.data[i].count + "\r\n" +
"response.data[i].link: " + response.data[i].link
);
aAlbums[i] = new Album(
response.data[i].id,
response.data[i].name,
response.data[i].count,
response.data[i].link
);
alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
}
alert("about to pass back the array to the callback function");
// pass the array back to the callback function sent as a param to the GetAllAlbums method here
callbackFunctionSuccess(aAlbums);
});
}
function BindAlbumAndPhotoData()
{
// Get an array of all the user's Albums
GetAllAlbums(userID, token, function(aAlbums){
// Set the default albumID
var defaultAlbumID = aAlbums[0].id;
});
};
and then in the GetAllAlbums function call the success function when you have the data back
//********* AFTER THE BREAK *******//
In response to the updated question: The FB API is mostly asynchronous, and will keep executing other code while it waits. So using your code, all I have done is passed in the function, and then call the function you've passed it at the end
function GetAllAlbums(userID, accessToken, funcSuccess)
{
var aAlbums = []; // array
var uri = "/" + userID + "/albums?access_token=" + accessToken;
alert("uri: " + uri);
FB.api(uri, function (response)
{
// check for a valid response
if (!response || response.error)
{
alert("error occured");
return;
}
for (var i = 0, l = response.data.length; i < l; i++)
{
alert("Album #: " + i + "\r\n" +
"response.data[i].id: " + response.data[i].id + "\r\n" +
"response.data[i].name: " + response.data[i].name + "\r\n" +
"response.data[i].count: " + response.data[i].count + "\r\n" +
"response.data[i].link: " + response.data[i].link
);
aAlbums[i] = new Album(
response.data[i].id,
response.data[i].name,
response.data[i].count,
response.data[i].link
);
alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
}
funcSuccess(aAlbums);
});
}
Is your function GetAllAlbums() doing some HTTP requests? If so then you need to either make that call synchronous or you need to put your code into a function and pass that as a callback to the Ajax request.
Try three equals signs instead of two, and also... return false rather than nothing at all.
if (aAlbums === null || aAlbums === undefined)
return false;
Also, undefined doesn't need to be in quotes, otherwise, it's just considered a string with a value of "undefined"
On an added note, it's probably better to ALSO check if aAlbums is actually an array before you decide to return a key from it.
if ( aAlbums === null
|| aAlbums === undefined
|| (typeof(aAlbums)=='object'&& !(aAlbums instanceof Array))
} return false;
Try modifying your condition like this:
if (typeof aAlbums == 'undefined')
return;
Also make sure that aAlbums has values and is an array:
alert(aAlbums.length);
Or:
for(var i = 0; i < aAlbums.length; i++)
{
alert(aAlbums[i].id);
}

Categories

Resources