I have one callback function
function QueryKeyword(keyword, site, callback) {
var querykeyword = keyword;
var website = site;
$.ajax({
url: "http://www.test.com",
jsonp: "jsonp",
dataType: "jsonp",
data: {
Query: querykeyword
},
success: callback
});
}
I am calling this function with in for loop like this :
for (i = 0; i < questionTerm.length; i++) {
for (j = 0; j < site.length; j++) {
var searchTerm = questionTerm[i] + ' ' + $('#search').val();
QueryKeyword(searchTerm, site[j], function(reslt) {
// I need to get j variable value here
console.log(j);
});
}
}
Now I need to get "j" variable value in function see I console the j variable value but it does not get the j variable value.
Would you please let me know how I can fetch the value in this.
Thanks in advance
The problem is, that at the moment of your callback, j was reassigned multiple times to something different.
There are a few options you could do.
call your callback with the params you need
function QueryKeyword(keyword, site, index, callback) {
// ...
$.ajax(
success: function(result) {
// call the callback with a second param (the index j)
callback(result, index);
}
)
}
QueryKeyword(searchTerm, site[j], j, function(reslt, param) {
// param is j
console.log(result, param);
});
save the var in a closure
(function() {
var value = j;
...
})();
use forEach
questionTerm.forEach((term, i) => {
site.forEach((s, j) => {
// we are in a closure,
// j will be correct here.
QueryKeyword(term, s, function(reslt) {
// j is still correct here
console.log(j);
});
})
});
if you use es6, you could use let keyword. Here is some good explanation, how it works when using for loops
for(let i = 0; i < 10; i++) {
console.log(i);
setTimeout(function() {
console.log('The number is ' + i);
},1000);
}
You have to pass it in separately:
definition
function QueryKeyword(keyword, site, index, callback)
{
...
}
execution
QueryKeyword(searchTerm, site[j], j, function(reslt) {
// I need to get j variable value here
console.log(j);
});
Related
var data = [{start_date:20180601,end_date:20180701},{start_date:20180801,end_date:20180901},{start_date:20181001,end_date:20181101},{start_date:20181201,end_date:20190101}];
var requests = [];
for (var i = 0; i < data.length; i++) {
(function(i, data) {
requests.push(function() {
jQuery.ajax({
url: 'https://reqres.in/api/users?page=1',
method: 'GET',
success: function(result) {
console.log(i); // 0
requests[i].apply(undefined, []);
}
});
});
console.log(i); //counts up
})(i, data);
};
requests[0].apply(undefined,[]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am wondering, how come with this code:
for (var i = 0; i < data.length; i++) {
(function(i, data) {
requests.push(function() {
jQuery.ajax({
url: wpApiSettings.root + 'superdooperendpoint/' + apikey + "/" + data[i].start_date + "/" + data[i].end_date,
method: 'GET',
beforeSend: function(xhr) {
// Set nonce here
xhr.setRequestHeader('X-WP-Nonce', wpApiSettings.nonce);
},
success: function(result) {
success_callback({
start_date: data[i].start_date,
end_date: data[i].end_date,
span: data[i].span,
result: result
});
console.log(i); // 0
requests[i].apply(undefined, []);
}
});
});
console.log(i); //counts up
})(i, data);
};
When I do the first console.log() in the success function it is always 0, not undefined, yet while outside of the success function it counts up in the iterating for loop. How can I get it to count up in the success function as well?
The following paints the updated value of i
Parallel Calls
var data = [{start_date:20180601,end_date:20180701},{start_date:20180801,end_date:20180901},{start_date:20181001,end_date:20181101},{start_date:20181201,end_date:20190101}];
var requests = [];
for (var i = 0; i < data.length; i++) {
(function(i, data) {
requests.push(function() {
jQuery.ajax({
url: 'https://reqres.in/api/users?page=1',
method: 'GET',
success: function(result) {
console.log(i);
}
});
});
})(i, data);
};
for (var i = 0; i < requests.length; i++) {
requests[i].apply(undefined, []);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Sequential Calls
var data = [{start_date:20180601,end_date:20180701},{start_date:20180801,end_date:20180901},{start_date:20181001,end_date:20181101},{start_date:20181201,end_date:20190101}];
var requests = [];
for (var i = 0; i < data.length; i++) {
(function(i, data) {
requests.push(function() {
jQuery.ajax({
url: 'https://reqres.in/api/users?page=1',
method: 'GET',
success: function(result) {
console.log(i);
i++;
if(i < requests.length) {
requests[i].apply(undefined, []);
}
}
});
});
})(i, data);
};
requests[0].apply(undefined, []);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Explanation - When you iterated over the function, for each function in requests array a value of i was passed/stored just like an argument. When you invoke the requests[0] from outside, on completion of the function, the stored value of i i.e. 0 is painted. And then, you again trigger the function stored at index = 0 i.e. you end up creating an infinite loop. In order to paint the appropriate value, loop over the requestsarray and call the individual function one by one to see the appropriate value of i being logged.
You need to assign i to a different local variable of the nested function and put the definition of i out of the block;
let i = 0;
for (; i < 100; i++) {
((n) => new Promise(
(res, rej) => setTimeout(res, 100)
).then(() => console.log(i,n))
)(i);
}
function get_stock_data(symbol, index) {
var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22"+ symbol +"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=";
$.getJSON(url, function(data) {
var price = $(".stock-price");
price[index].innerHTML = "";
price[index].appendChild(document.createTextNode(data.query.results.quote.Change));
console.log(data);
}).success(function() {
console.log("success");
}).fail(function() {
console.log("Failed");
});
}
$("document").ready(function() {
var symbol = $(".stock-symbol");
for(var i = 0; i < symbol.length; i++) {
setInterval(get_stock_data(symbol[i].firstChild.textContent, i) , 1000);
console.log("hello");
}
});
The problem in this script is that get_stock_data function executes only once...plz help...i want the data to be updated to DOM..
Something like this should work.
function get_stock_data(symbol, index) {
var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22" + symbol + "%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=";
$.getJSON(url, function (data) {
var price = $(".stock-price");
price[index].innerHTML = "";
price[index].appendChild(document.createTextNode(data.query.results.quote.Change));
console.log(data);
}).success(function () {
console.log("success");
}).fail(function () {
console.log("Failed");
});
}
function setUpInterval() {
var symbol = $(".stock-symbol");
for (var i = 0; i < symbol.length; i++) {
setInterval("get_stock_data(" + symbol[i] + "," + i + ")", 1000);
}
}
setUpInterval();
You are calling get_stock_data in your setInterval call. So it gets called once and only once. You are actually passing undefined to setInterval, because get_stock_data doesn't return anything.
The first argument of setInterval should be the function you want to call. In this case, it looks like you want to call get_stock_data with some passed-in parameters. To make this work with setInterval, you'll need to pass in an anonymous function like this:
for (var i = 0; i < symbol.length; i++) {
setInterval(function() { get_stock_data(symbol[i].firstChild.textContent, i); }, 1000);
}
This way you are passing in the function to setInterval, which setInterval will call every 1000 (or so) milliseconds.
I am trying to create an array from an asynchronous get request using a function that uses a for loop in order to pass a parameter in the get request.
var loadRarity = function () {
var rarities = [];
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
rarities.push(data.data[0].rarity);
console.log(rarities); //20 instances where the array is being populated
});
console.log(rarities);// result :20x [] empty array
}
return rarities;
};
var raritiesArray = loadRarity();
console.log(raritiesArray); //empty array
I can't figure out how to use the callback to make this work.
An option is to increment a counter to check if you are on the last callback an then do any needed operation in that last callback
var loadRarity = function () {
var rarities = [];
var counter = 0; // initialize counter
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
counter += 1; //increment counter
rarities.push(data.data[0].rarity);
console.log(rarities); //20 instances where the array is being populated
if(counter == deck.length){ //if true you are in the last callback
console.log(raritiesArray); // array with all the elements
}
});
}
return rarities;
};
var raritiesArray = loadRarity();
Waiting for all this async stuff to happen, your code that needs to use the result should be in its own callback, which runs when the result is available. For example:
var loadRarity = function(cb) {
var rarities = [],
counter = 0,
done = function(){
if(counter++ === deck.length - 1){
cb(rarities);
}
};
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
rarities.push(data.data[0].rarity);
done();
});
}
};
loadRarity(function(completedRarities){
console.log(completedRarities);
});
Sample (using an image onload fn to simulate your asysnc call): http://codepen.io/RwwL/pen/VeeEBR?editors=001
I want to create a loop for input so that the variable img get number 1 to 5 like this:
img1, img2 ... img5.
How to write $i after img?
for ($i=1;$i<=5;$i++) {
function(data) { $('input[name="img1"]').val(data) });
}
Note: img is between two quotation mark.
it's edite:
user = $('input[name="name"]').val();
for (var i = 1; i <= 5; i++) {
$.post("test.php", { name: user, num: i },
function(data) {
$('input[name="img'+i+'"]').val(data)
});
}
The function you have declared in your loop seems weird. That's not valid javascript. You may try the following:
for (var i = 1; i <= 5; i++) {
$('input[name="img' + i + '"]').val(data);
}
or if we suppose that you have defined some function:
var foo = function(data, index) {
$('input[name="img' + index + '"]').val(data);
}
you could invoke it like this:
for (var i = 1; i <= 5; i++) {
foo('some data ' + i, i);
}
UPDATE:
An interesting example was provided in the comments section:
for (var i = 1; i <= 5; i++) {
$.post(
"test.php",
{ name: username, num: i },
function(data) {
$('input[name="img'+i+'"]').val(data);
}
);
}
This won't work because the i variable might have changed value between the loop and the AJAX success callback. To fix this you may try the following:
for (var i = 1; i <= 5; i++) {
(function(index) {
$.post(
"test.php",
{ name: username, num: index },
function(data) {
$('input[name="img'+index+'"]').val(data);
}
);
})(i);
}
or use the $.ajax() method which allows you to pass a context to the success callback:
for (var i = 1; i <= 5; i++) {
$.ajax({
url: 'test.php',
type: 'POST',
data: { name: username, num: i },
context: i, // here we are defining the context
success: function(result) {
// since we have used the context parameter, this variable
// here will point to the value that i had when we initiated
// the AJAX request
$('input[name="img' + this + '"]').val(result);
}
});
}
Like this:
for ($i=1;$i<=5;$i++) {
function(data) { $('input[name="img' + $i + '"]').val(data) });
}
By the way, I'm guessing you'e coming from a PHP background, but in JavaScript it is not conventional to use $ for variable names (except sometimes for jQuery objects). So normally you'd write your code like this:
for (i=1;i<=5;i++) {
function(data) { $('input[name="img' + i + '"]').val(data) });
}
I get stacked on a looping issue and couldn't get it.
for (var i = 0; i < count; i++) {
FB.api({
method: 'fql.query',
query: 'SELECT name FROM user WHERE uid=' + temparray[i]
}, function (response) {
for (var x = 0; x < count; x++) {
$("#divfather" + x).html(response[0].name);
}
});
}
The second loop is done through response[0].name which is the name of Facebook and showing me the same response for all divs.
I want only this second loop being done to the i variable.
How can I do it?
It's a little hard to understand what you want, but I assume you only want the i from the outer for loop.
You'll need to create a new variable scope in order to retain it.
for (var i = 0; i < count; i++) {
FB.api({
method: 'fql.query',
query: 'SELECT name FROM user WHERE uid=' + temparray[i]
}, (function( j ) { // <---- create a function...
// v---------...that returns a function...
return function (response) {
$("#divfather" + j ).html(response[0].name);
};
})( i ) // <------...and invoke it immediately, passing "i"
);
}
Here's the same thing, but using a named function, which I think is a little nicer.
function get_callback( j ) {
return function (response) {
$("#divfather" + j ).html(response[0].name);
};
}
for (var i = 0; i < count; i++) {
FB.api({
method: 'fql.query',
query: 'SELECT name FROM user WHERE uid=' + temparray[i]
}, get_callback( i ) );
}
Or personally, I'd place all the logic in the function instead of splitting it up.
function set_up_FB_api( j ) {
FB.api({
method: 'fql.query',
query: 'SELECT name FROM user WHERE uid=' + temparray[ j ]
}, function (response) {
$("#divfather" + j ).html(response[0].name);
});
}
for (var i = 0; i < count; i++) {
set_up_FB_api( i );
}
You have a scope issue sken boy.
You are using i in the outer loop and then redeclaring it in the inner loop.
Change the second loop to some other letter like x.