I am using this piece of code to retrieve some JSONs from twitch:
for (var i = 0; i < streamList.length; i++) {
$.get(baseURL + streamList[i], getStreamInfo, "json");
}
where getStreamInfo is the callback function. I would like to know if it is possible to pass the value of "i" to the callback function somehow, along with the JSON.
Yes, you can pass the default parameter that receive the data of the ajax query and then add the i var.
for (var i = 0; i < streamList.length; i++) {
$.get(baseURL + streamList[i],
function(data) { getStreamInfo(data, i) },
"json");
}
Note that you need to receive it in getStreamInfo function
Hope it helps.
You can add any variables you want to the anonymous object. Be sure those variables are not used by the get function.
For exemple, I added the variable foo to the anonymous object and used it with this.foo in the callback function :
for (var i = 0; i < streamList.length; i++) {
$.get({
url: baseURL + streamList[i],
success: getStreamInfo,
dataType: "json",
foo:i
});
}
function getStreamInfo()
{
var i = this.foo;
}
You can use Closures.
for (var i = 0; i < streamList.length; i++) {
(function(index){
$.get(baseURL + streamList[i], function(data){
getStreamInfo(data, index);
}, "json");
})(i);
}
Note: Modify your function getStreamInfo to accept index.
Read How do JavaScript closures work?
Related
I am newbie in javascript, I want to do looping normally use "for". I would like to duplicate this script about 10 ...
how loop this script?
function getComboMotif1() {
$.get("file.php?opt1=" + $("#id1"), function (data) {
$("#asd1").html(data);
});
}
The manual Loop script like this !!
function getww1() {
$.get("file.php?opt1=" + $("#id1"), function (data) {
$("#asd1").html(data);
});
}
function getww2() {
$.get("file.php?opt1=" + $("#id2"), function (data) {
$("#asd1").html(data);
});
}
function getww3() {
$.get("file.php?opt1=" + $("#id3"), function (data) {
$("#asd1").html(data);
});
} //and further
Something like that :
function getResource(which) {
$.get('file.php?opt1=' + $('#id' + which), function (data) {
$('#asd' + which).html(data);
}
}
for (var i = 0, max = 3; i < max; i += 1) {
getResource(i);
}
But your code contains a few oddities.
$('#id1') is a jquery object, so it can't be sent to the server as a string.
If you always replace the $('#asd1').html(data) in each callback, it will get overwritten each time you get an answer from the server. That's why I made it dynamic also.
If you need it to just run through a forloop, then start at 1 in order to accommodate your name and id.
for(var i = 1; i <= 10; ++i)
$.get("file.php?opt1=" + $("#id" + i), function (data) {
$("#asd1").html(data);
});
Now since get is asynchronous, each one will not wait for the other to complete.
If you need each function to be created, getww1 and such, then I recommend using eval to create those functions for you. But, that is very inefficient to do and should be avoided unless there is a specific requirement. Ex:
...
eval("(function () { return function "
+fname+" (){"+
codeAsString
+"};})()"));
...
That will return the newly created function.
I hope this helps to some degree.
I post here a snippet of code where I get a runtime error. The variable x changes is value inside an ajax call:
$("#acquisto").click(function(){
var x = 0;
for(x = 0; x < numRighe; x++){
if( $("#ch"+x).prop("checked") == true){
alert("#tr"+x);
$.ajax({
url:"eliminazioneRecord.php",
type: "GET",
data: { Codice: $("#ch"+x).val() },
success:function(result){
//$("#tr"+x).fadeOut("slow");
alert("#tr"+x);
},
error:function(richiesta,stato,errori){
alert("<strong>Chiamata fallita:</strong>"+stato+" "+errori);
}
});
}
}
});
I realized that because the in the alert before the ajax call x has a value that is different from the one showed in the alert inside the success function. Where I am wrong?
All the anonymous functions passed to success in $.ajax reference the same x variable from the outer scope which is incremented by the for structure. You need each function to have it's own copy of x.
success:function(copy_x) {
return function(result){
//$("#tr"+copy_x).fadeOut("slow");
alert("#tr"+copy_x);
}
}(x),
It is because your are using the loop variable x in a closure within the loop.
$("#acquisto").click(function () {
for (var x = 0; x < numRighe; x++) {
(function (x) {
if ($("#ch" + x).prop("checked") == true) {
alert("#tr" + x);
$.ajax({
url: "eliminazioneRecord.php",
type: "GET",
data: {
Codice: $("#ch" + x).val()
},
success: function (result) {
//$("#tr"+x).fadeOut("slow");
alert("#tr" + x);
},
error: function (richiesta, stato, errori) {
alert("<strong>Chiamata fallita:</strong>" + stato + " " + errori);
}
});
}
})(x)
}
});
Read:
Creating closures in loops: A common mistake
Javascript closure inside loops - simple practical example
This is to populate a table with the amount of results that are returned from the MediaWiki API query /api.php?action=query&list=querypage&qppage=BrokenRedirects. The number of results is then added to the id, for example:
// BrokenRedirects
$.getJSON('/api.php?action=query&list=querypage&qppage=BrokenRedirects&format=json', function (data) {
$('#BrokenRedirects').text(data.query.querypage.results.length);
});
But as it's being repeated another 7 times I made the arguments for qppage into an array and used a for loop to shorten overall code.
var array = ['BrokenRedirects',
'DoubleRedirects',
'Unusedcategories',
'Unusedimages',
'Wantedcategories',
'Wantedfiles',
'Wantedpages',
'Wantedtemplates'];
for (var i = 0; i < array.length; i++) {
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
}
The first, unlooped, version works. But when I added a loop it didn't. The $getJSON part executes, but it then fails to add the resultant data to the id. I ran it through JSLint which apart from complaining about functions in a loop and declaring var i with var array returned little help. I'm relatively inexperienced with javascript so thought perhaps a variable can't be used twice within a loop? Other than that, maybe something to do with using an id within a loop?
That's a classical problem : i has the value of end of loop when the callback is called.
You can fix it like this :
for (var i = 0; i < array.length; i++) {
(function(i) { // protects i in an immediately called function
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
})(i);
}
2018 addendum:
There's now another cleaner solution in today's browsers: use let instead of var:
for (let i = 0; i < array.length; i++) {
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
}
getJSON is an asynchronous ajax call
REFER: use synchronous ajax calls
Use Jquery $.each() to iterate over the array instead of a for loop.
For example:
$.each(array, function(_, value) {
var url = '/api.php?action=query&list=querypage&qppage=' + value + '&format=json';
$.getJSON(url, function (data) {
$('#' + value).text(data.query.querypage.results.length);
});
});
You should write a function like -
function callUrl(value)
{
$.getJSON('/api.php?action=query&list=querypage&qppage=' + value + '&format=json', function (data) {
$('#' + value).text(data.query.querypage.results.length);
});
}
and then call it with some timeout option like -
setTimeout('callUrl(+ array[i] +)',500); within the loop -
i.e.
for (var i = 0; i < array.length; i++) {
setTimeout('callUrl(+ array[i] +)',500);
}
Some delay for each call will be required here.
I have a function that is similar to this:
function foo(array1, fun) {
var n;
n = a.length;
var i;
for (i=0; i<=n; i++) {
fun(a[i]);
}
}
Now I want to create a function called mult(x) that I will pass into foo when I call it. My question is what do I put in the parameters of my mult function when I want to call:
foo(some_array, mult(x));
Just pass in a reference to it (its name only)...
foo(some_array, mult);
Alternatively, pass in an anonymous function...
foo(some_array, function() { ... });
The first argument of this function you pass in with will be set to a[i] like in the body on your function.
Rewritten to showcase how you call a function in JS
function mult(x){
//do stuff to x
}
function foo(array1, fun){
var n = array1.length;
var i;
for (i=0; i<=n; i++) {
mult(array1[i]);
}
}
for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, function()
{
console.log(somearray[i][0]);
});
}
How do I pass somearray or one of its indexes into the anonymous function ?
somearray is already in the global scope, but I still get somearray[i] is undefined
The i in the anonymous function captures the variable i, not its value. By the end of the loop, i is equal to somearray.length, so when you invoke the function it tries to access an non-existing element array.
You can fix this by making a function-constructing function that captures the variable's value:
function makeFunc(j) { return function() { console.log(somearray[j][0]); } }
for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, makeFunc(i));
}
makeFunc's argument could have been named i, but I called it j to show that it's a different variable than the one used in the loop.
How about a closure:
for (var i = 0; i < somearray.length; i++) {
var val = somearray[i][0];
myclass.foo({'arg1': val}, function(v) {
return function() {console.log(v) };
}(val) );
}
for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, function(somearray)
{
console.log(somearray[i][0]);
});
}
And then in method foo call anonymous function with param.
You can pass variables values to annoymous function by using callback,
something like
myclass.foo(function(variable){
return function(){
console.log(variable);
}
})(variableValue);
);
check this post: https://shahpritesh.wordpress.com/2013/09/06/javascript-function-in-loop-passing-dynamic-variable-value/
All the functions/methods can be used as callbacks only. When you call the callback function you pass variables to it.
var myclass = {
foo: function(params, callback){
// do some stuff
callback(variable1, variable1, variableN);
}
}