My question is relatively straight forward.
I have an array of deferreds waiting to be returned, the code is like this:
var deferreds = [];
for(var i = 0; i < 5; i==){
deferreds.push(getOneResult(params));
}
var deferreds = [];
for(var i = 0; i < 5; i==){
deferreds.push(getOneResult(params));
}
The "getOneResult" function looks like this:
function getOneResult(params){
return $.ajax({
url: myURL,
data: params
});
}
It worked fine until one day I decided to let the "getOneResult" function to execute another ajax process and then using the result from this ajax process to get the result, so now my problematic code looks like this:
function getOneResult(params){
$.ajax({
url: myOtherURL,
data: params,
success: function(){
var result = arguments;
return $.ajax({
url: myURL,
data: arguments
});
}
});
}
Then all of a sudden all the items in "deferreds" array become "undefined". I am sure what I am doing sounds not right but is there anyway for me to run an ajax process before returning the deferred?
try returning the second promise. The original promise will now use the wrapped, second ajax promise.
function getOneResult(params){
return $.ajax({
url: myOtherURL,
data: params
}).then(function() {
return $.ajax({
url: myURL,
data: arguments
});
});
}
Related
I have two ajax calls, one of which is conditional i.e.
var url1Response, url2Response;
var def1 = $.ajax({
url: Url1,
success: function (response) {
url1Response= response;
}
});
var def2 = $.ajax({
url: Url2,
success: function (response) {
url2Response= response;
}
});
var defs = [];
defs.push(def1);
if (x == 1) // some condition
defs.push(def2);
$.when.apply($, defs).then(_self.callback, _self.failureCallback);
_self.callback = function (response) {
};
_self.failureCallback = function (response) {
};
When both the def are being executed I am not able to see both the responses in callback input parameter. I am able to see only the url1Response.
Could someone please help me how to handled such conditional deferred statement response i.e. only1 ajax executed, both executed, both executed but one failed etc.?
That's because when you use $.when.apply($, defs), each response will be send to then as a different parameter. So, you can take it as:
_self.callback = function (response1, response2) {
};
or even you can use spread syntax:
_self.callback = function (...responses) {
// response is a array with all responses
};
I have the following Ajax call:
for (var i=0;i<localStorage.length;i++){
stored = localStorage.getItem(i.toString());
id=stored.split(':');
if ( id[0].toString()=="legislator" ){
bioguide_id=id[1];
$http({
method: 'GET',
url: 'getData.php',
params: {fav_legislator_value: bioguide_id}
}).then(function (response) {
fav_legislators.push(response.data.results[0]);})
}
}
I need all the Ajax call to complete and all results pushed to the array after that only I can start processing again. I have tried many ways by making this a function but nothing works. My whole script gets executed then the values are pushed to the array which is of no use to me. How to wait until all the calls are completed and the array is completely populated.
Store all the promises object into an array, and use $q.all to combine all promises into a single promise which will be resolved only if all of them have been resolved.
E.g.
var promises = [];
for (var i=0;i<localStorage.length;i++){
stored = localStorage.getItem(i.toString());
id=stored.split(':');
if ( id[0].toString()=="legislator" ){
bioguide_id=id[1];
var req = $http({
method: 'GET',
url: 'getData.php',
params: {fav_legislator_value: bioguide_id}
}).then(function (response) {
fav_legislators.push(response.data.results[0]);
});
promises.push(req);
}
}
$q.all(promises).then(function () {
// All result is now in `fav_legislators`.
})
I have this jQuery function:
var searchResultsCounter = 0;
function searchPerson(filterText){
//code
$.ajax({
type: "GET",
dataType:"json",
url: "res/main.php",
data: { command : "loadPeople",
filter: filterText },
success: function( people ){
for(var i = 0; i< people.length; i++){
//code
}
searchResultsCounter = people.length;
console.log(searchResultsCounter);
}
});
console.log(searchResultsCounter);
return searchResultsCounter;
}
In the first console log, my searchResultsCoutner has a good value, at the second log, it becomes 0. Why is this happening?
The ajax request is executed asynchronously, so the success callback function which tries to alter the variable will be executed later.
Your function simply returns 0. You have to rewrite your code that it works an asynchronous way. One way would be to pass a callback function to searchPerson as a parameter.
Return from searchPerson() function the promise interface ($.ajax) and use returned result once deferred is resolved:
function searchPerson(filterText) {
//code
return $.ajax({
type: "GET",
dataType: "json",
url: "res/main.php",
data: {
command: "loadPeople",
filter: filterText
}
});
}
$.when(searchPerson(filterText)).done(function (data) {
/*SUCCESS*/
});
so this is my setup: I am calling a .each on a number of elements and after a few checks I send an ajax request with some JSON data and on success I apply the server response as an attribute to each element(it is usually an id). After that I push the id to an array.
The problem is that obviously ajax requests are asynchronous and the function that uses the array of element ids fires before all ajax have had time to finish.
I've tried with .when and .then but the callback function keeps getting fired way ahead of the ajax.
Here is how my code looks( I've removed some unnecessary parts):
var order = [];
function sub(selector){
selector.each(function(){
var out = {
"some":"random",
"stuff":"here"
};
$.ajax({
type: "POST"
url: "/test/url",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data:JSON.stringify(out),
success:function(response){
$(this).attr("data-response",response);
order.push(response);
}
})
})
}
$("#button").click(function(){
$.when(sub($(".test"))).then(function() {
console.log(order);
//i have to run the sub function twice so the order doesn't return undefined
});
});
The problem is that when acts on deferred objects, however sub doesn't return anything so when fires right away. So what you need to do is to collect all the deferred objects returned by the ajax calls and return them:
var order = [];
function sub(selector){
var deferredList = []
selector.each(function(){
var out = {
"some":"random",
"stuff":"here"
};
var deferred = $.ajax({
type: "POST",
url: "/test/url",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data:JSON.stringify(out),
success:function(response){
$(this).attr("data-response",response);
order.push(response);
}
})
deferredList.push(deferred)
})
return deferredList;
}
$("#button").click(function(){
$.when.apply($,sub($(".test"))).then(function() {
console.log(order);
//i have to run the sub function twice so the order doesn't return undefined
});
});
The reason to use apply and not when directly is that when doesn't accept array of objects as a parameter and apply provides us the work-around for this.
The argument to $.when() should be a Deferred, but sub() doesn't return anything. This version returns an array of all the Deferreds returned by $.ajax, and calls $.when with them all as arguments; it will then wait for all of them.
var order = [];
function sub(selector){
return selector.map(function(){
var out = {
"some":"random",
"stuff":"here"
};
return $.ajax({
type: "POST"
url: "/test/url",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data:JSON.stringify(out),
success:function(response){
$(this).attr("data-response",response);
order.push(response);
}
})
})
}
$("#button").click(function(){
$.when.apply(this, sub($(".test"))).then(function() {
console.log(order);
//i have to run the sub function twice so the order doesn't return undefined
});
});
Your approach produces a whole lot of more server requests and will scale terribly. Since you want to wait for all results anyway, a much better solution would be to collect all data and send only one ajax request which returns an array of results for each data object.
Using a deferred object (as seen in other answers) then gives you the ability to use that result in a when statement.
try to use a callback-function in success:
var order = [];
function sub(selector, callback){
selector.each(function(){
var out = {
"some":"random",
"stuff":"here"
};
$.ajax({
type: "POST"
url: "/test/url",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data:JSON.stringify(out),
success:function(response){
$(this).attr("data-response",response);
order.push(response);
callback();
}
})
})
}
$("#button").click(function(){
sub($(".test"), function() { console.log(order) });
});
Add attribute async : false to your $.ajax - call. Then the calls are made in sequence after eachother.
I'm experimenting with MCV using jquery. I'm making a call to an api, which returns data - what I want to do is return the data to a variable rather than call an additioanl function within my model. The following code doesn't do what I wish though (the_data = result). Any ideas how I can achieve this?
function lookForSomething()
{
var the_data = $.ajax({ type: "GET",
url: TheUrl,
dataType: "jsonp",
success: function(result) { return result; }
});
return the_data;
}
Many thanks,
J
If understand you correctly, you want the data returned by TheUrl to be the return value of the lookForSomething.
Technically, you could do this, with the async option:
function lookForSomething()
{
var the_data;
$.ajax({ type: "GET",
url: TheUrl,
dataType: "jsonp",
async : false,
success: function(result) { the_data = result; }
});
return the_data;
}
I strongly urge you not to do this. It's un-Javascript-like and it will lock up the user's browser while it's running. Much better to pass in a callback to the function and invoke it from success.
You are probably looking for deferred objects:
function lookForSomething()
{
var the_data;
$.when(
$.ajax({ type: "GET",
url: TheUrl,
dataType: "jsonp",
success: function(result) { the_data=result; }
});
).done(function() {
return the_data;
}).fail(function() {
return '';
});
}
Keep in mind that this is still asynchronous, so when you make a call for var ddd = lookForSomething();, ddd will not have the value you expect since the call may still be running. The only reason I brought up $.when() is because it seems like you require a lot of dependencies. $.when() allows you to wait for multiple ajax commands.