jQuery Wait until async ajax calls are finished - javascript

Hi I have 2 ajax calls in my script, I need them run asnyc to spare time, but I need the second to wait until the first is finished.
$.ajax({
type: "POST",
url: "getText.asmx/ws_getText",
data: parO1,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d.data);
},
error: function () {
chyba("chyba v požadavku", "df");
}
});
if (parO2.length > 0) {
$.ajax({
type: "POST",
url: "getText.asmx/ws_getText",
data: parO2,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
/*WAIT UNTIL THE FIRST CALL IS FINISHED AND THAN DO SOMETHING*/
},
error: function () {
chyba("chyba v požadavku", "df");
}
});
}
So any ideas? Thanks

If using jQuery 1.5+, you can use jQuery.when() to accomplish this. Something like (shortened the ajax calls for brevity, just pass the objects as you're doing above)
$.when($.ajax("getText.asmx/ws_getText"),
$.ajax("getText.asmx/ws_getText")).done(function(a1, a2){
// a1 and a2 are arguments resolved for the
// first and second ajax requests, respectively
var jqXHR = a1[2]; // arguments are [ "success", statusText, jqXHR ]
});
You don't know in which order they will return so if you were rolling this by hand, you would need to check the state of the other request and wait until it has returned.

You need to wire up the second call to be contained within the callback of your first ajax call. Like so:
success: function(msg)
{
alert(msg.d.data);
if(par02.length > 0)
{
// Your 2nd ajax call
}
},
Since JavaScript doesnt run in multiple threads on the client, you can't block the thread until certain conditions are met.

Using jquery
$.ajax({
type: "POST",
async:false, // ** CHANGED **
url: "getText.asmx/ws_getText",
data: parO1,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d.data);
}
, error: function () {
chyba("chyba v požadavku", "df");
}
});

Here is another answer on running dual ajax requests. Like Tejs, the user makes an ajax call within the success method...
The poster states You're better off having the success method launch a new ajax request.."
Having two $.ajax() calls in one script

Related

MissMatching parameters in ajax call, try catch block

How to identify mismatching of parameters on a ajax call ? I have the following code sample
var driverId = $('#driverId').val();
var driverPhoneNumber = $('#driverPhoneNumber').val();
$.ajax({
type: "POST",
url: 'srvl_def',
cache: false,
contentType: "application/x-www-form-urlencoded; charset=UTF-8;",
dataType: "json",
data: {
driverId: driverId,
driverPhoneNumber: driverPhoneNumber
},
success: function (data) {
alert(data.mensaje);
}
});
My AJAX calls are much more complex than this. I have close to 80 parameters at some places. Missing a parameter it becomes impossible traceback and its very time consuming. Also when parameters are undefined it takes time to debug that. Is there a way in which I can use a try catch block to print out all the undefined and non matching parameters of my ajax ?

Second Ajax call already populated with success results

I have an Ajax call being made from a button press which returns me some data then goes off and creates a grid. The first time the function is called the Ajax call is made, data is returned and the grid is displayed. Happy Days.
However any subsequent call to the function, where none of the data parameters are changed, result in the Ajax call not being made to the server and the function skips straight to 'success' with the results from the successful call already populated.
Changing any of the 'postParameters' results in a successful Ajax call and the data is refreshed.
function btnClick(){
//blah blah
getGridData();
}
function getGridData() {
var postParameters =
{
SiteID: "#Model.SiteID",
DateFilterFrom: $("#datepickerFrom").val(),
DateFilterTo: $("#datepickerTo").val(),
CustomerFilter: $("#customers").val()
};
$.ajax({
url: "#Url.Action("SalesForecast_Read", "Planning")",
type: "GET",
contentType: "application/json; charset=utf-8",
data: postParameters,
dataType: "json",
success: function (results) {
createHighlights(results.Highlights);
createGrid(results.Entries);
},
error: function (e) {
alert(e.responseText);
}
});
};
I know there must be an important Javascript concept I am missing but I just cant seem to be able to nail it.
Can anyone help put me in the right direction?
Have you tried to disable the cache with:
$.ajax({
url: "#Url.Action("SalesForecast_Read", "Planning")",
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
data: postParameters,
dataType: "json",
success: function (results) {
createHighlights(results.Highlights);
createGrid(results.Entries);
},
error: function (e) {
alert(e.responseText);
}
});
Explanations
The cache basically tries to save a call to the server by saving the return value of the calls.
It saves them using a hash of your query as a key, so if you make a second query that is identical, it will directly return the value from the cache, which is the value that was returned the first time.
If you disable it, it will ask the server for every query.
You can add cache: false to your ajax request.
$.ajax({
url: "#Url.Action("SalesForecast_Read", "Planning")",
type: "GET",
contentType: "application/json; charset=utf-8",
data: postParameters,
dataType: "json",
cache:false,
success: function (results) {
createHighlights(results.Highlights);
createGrid(results.Entries);
},
error: function (e) {
alert(e.responseText);
}
});
IE might not listen to you though. For that you can add a field to the POST Parameters, where you add the current time in miliseconds, so even IE does not cache.
try to add this in ur ajax call:
$.ajax({
cache: false,
//other options...
});
This will force the recall of the ajax each time.
For more information please check the following link :
api.jquery.com/jquery.ajax

Jquery - Calling a ajax function within ajax function

Can I use ajax function withing a ajax function.
In my case there are two ajax calls. First ajax will return some data , If it is successful then the second ajax should be called .
Below is my code snippet,
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
async: false,
url: "my service url here"
dataType = "json",
//success - 1
success: function(data) {
//I ll collect the data from service
//now the second ajax must run.
//Because in first call I ll receive some data
//That data I going to use in my second call
$.ajax({
alert('inside ajax-2');
type: "GET",
contentType: "application/json; charset=utf-8",
async: false,
url: "my second service URL here",
dataType: "json",
//success - 2
success: function(data) {
//some functionality
} //success-2
} //success-1
}); //ajax - 2
}); //ajax - 1
Some more info :
I had checked chrome dev console and the error I am getting is
//success - 1
success: function(data) {
//Error message : Uncaught SyntaxError: Unexpected identifier
That was the error message I got.
And yes I cleared the syntactical mistakes and I was getting the same error message.
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
async: false,
url: "my service url here",
dataType : "json"
//success - 1
success: function(data) {
//I ll collect the data from service
//now the second ajax must run.
//Because in first call I ll receive some data
//That data I going to use in my second call
$.ajax({
alert('inside ajax-2');
type: "GET",
contentType: "application/json; charset=utf-8",
async: false,
url: "my second service URL here",
dataType: "json",
//success - 2
success: function(data) {
//some functionality
} //success-2
} //success-1
}); //ajax - 2
}); //ajax - 1
I checked the service URL in RESTClient extension of firefox browser and again yes , there is Jsondata coming from that service.
Any good suggestion will be highly appreciable
Merry Christmas :)
There are some errors in your scripts.
In the first ajax call, where are the commas to separate the members ?
url:"my service url here",
dataType= "json",
and this should be:
dataType : "json",
Going back to your answer, yes you can but, what if you had the third ajax call?
Your code would be a mess and really hard to read.
The best would be to use promises.
This is the best way to work with asynchronous in javascript (that's also the reason why I've commented your async:false ).
You can read how promises work here.
$.ajax already returns a promise:
var promise = $.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url:"my service url here",
dataType: "json",
});
which could be chained with another one:
promise.then(function(result){ });
I tend to prefer the approach where I split my ajax call in different function which create a new promise and return it; just in case I want to manipulate the result:
You can split the two ajax calls:
function FirstAjaxCall()
{
var deferred = $.Deferred();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
// async : false,
url:"my service url here",
dataType: "json",
success: function (jsonData) {
deferred.resolve(jsonData);
},
error: function (req, status, error) {
var errorMessage = (error.message) ? error.message : error;
deferred.reject(errorMessage);
}
});
return deferred.promise();
}
and
function SecondAjaxCall()
{
var deferred = $.Deferred();
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
// async:false,
url: "my second service URL here",
dataType: "json",
success: function (jsonData) {
deferred.resolve(jsonData);
},
error: function (req, status, error) {
var errorMessage = (error.message) ? error.message : error;
deferred.reject(errorMessage);
}
});
return deferred.promise();
}
Now you could resolve the first one and chain the second one:
FirstAjaxCall()
.then(function(result){
return SecondAjaxCall(result);
})
.then(function(result){
// final result
})
.fail(function(reason){
// reason should contain the error.
});
As you can see FirstAjaxCall() is resolve in the .then() branch and it passes it's result in the anonymous function. Same thing happens with the second ajax call SecondAjaxCall(). If something fails in the first or the second call the errors are trapped here:
.fail(function(reason){
// reason should contain the error.
});
The beauty of promises is you can chain them or execute them in parallel.
Yes you can.
Something wrong in your code that I can see is that }//success-1 is before });//ajax - 2 and it should be after.
also there is a missing coma ( ,) after url:"my service url here",
replace the '=' you have by ':' for your two dataTypes.
your should correct that and try again.
Try something like below in a structured way:
//First method with callback
function myFirstCall(callback) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
async:false,
url:"my service url here",
dataType= "json",
success:function(data){
callback();
});
}
// Second method
function mySecondCall() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
async:false,
url:"my second service url here",
dataType= "json",
success:function(data){
});
}
//Let's trigger it
myFirstCall(function() {
mySecondCall();
});
You have to change "=" after the first "dataType" to ":"
dataType= "json", => dataType : "json",
and move "alert" function to the outside the second $ajax block.
$.ajax({ => alert('inside ajax-2');
alert('inside ajax-2'); $.ajax({
Last, order of closing brackets are opposite.
}//success-1 => });//ajax - 2
});//ajax - 2 }//success-1
The following code should work as you thought.
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
async:false,
url:"my service url here"
dataType : "json",
//success - 1
success:function(data){
//I ll collect the data from service
//now the second ajax must run.
//Because in first call I ll receive some data
//That data I going to use in my second call
alert('inside ajax-2');
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
async:false,
url: "my second service URL here",
dataType: "json",
//success - 2
success: function (data) {
//some functionality
}//success-2
});//ajax - 2
}//success-1
});//ajax - 1

Using Q,js for ajax calls

I have an ajax call that might take a bit to complete. I don't want to use async:false because I want it to stay non blocking code. So I decided to use Q. The problem is I don't understand how ca I extract the json that came back from Q.when($.ajax...). I'm new to Q.
In this example I would like the variable to hold the json that came back from the server:
var res = Q.when($.ajax({
type: "POST",
url: "GetData.asmx/GetMembersList",
contentType: "application/json; charset=utf-8",
dataType: "json"
}));
return res;
With asynchronous calls you can't just assign the result to a variable, because that result won't exist until sometime in the future. Q.when does not return the result, it returns a promise object that will eventually resolve with a result.
If there is only ever one thing you want to do with the JSON you could just inline a .then call to get the result.
Q($.ajax({
type: "POST",
url: "GetData.asmx/GetMembersList",
contentType: "application/json; charset=utf-8",
dataType: "json"
})).then(function (res) {
// res now contains the JSON
});
However the real power of promises comes with the fact that you can pass them around and use them later.
function getMembersList() {
return Q($.ajax({
type: "POST",
url: "GetData.asmx/GetMembersList",
contentType: "application/json; charset=utf-8",
dataType: "json"
}));
}
var membersList = getMembersList();
membersList.then(function (res) {
// once the AJAX call completes this will
// run. Inside this function res contains the JSON
return res; // pass res to the next chained .then()
}).then(function (res) {
// you could chain another then handler here
});
// do some other stuff
membersList.then(function (res) {
// you could also add another then handler later too
// even long after the AJAX request resolved and this
// will be called immediately since the promise has already
// resolved and receive the JSON just like the other
// then handlers.
});
You don't need to use Q if you don't have other reasons for using it, since version 1.5 jQuery returns a deferred object from AJAX calls. A Deferred is similar to a promise. Q does offer more power and jQuery's promises/deferreds don't exactly implement the Promises/A standard, potentially causing problems with error handling. For something simple like an AJAX call jQuery promises are usually good enough if you are already using jQuery anyway.
var membersList = $.ajax({
type: "POST",
url: "GetData.asmx/GetMembersList",
contentType: "application/json; charset=utf-8",
dataType: "json"
});
membersList.then(function (res) {
// res now contains the JSON
});
Here are some examples from the q documentation about using with jQuery ajax.
return Q(jQuery.ajax({
url: "foobar.html",
type: "GET"
})).then(function (data) {
// on success
}, function (xhr) {
// on failure
});
// Similar to jQuery's "complete" callback: return "xhr" regardless of success or failure
return Q.promise(function (resolve) {
jQuery.ajax({
url: "foobar.html",
type: "GET"
}).then(function (data, textStatus, jqXHR) {
delete jqXHR.then; // treat xhr as a non-promise
resolve(jqXHR);
}, function (jqXHR, textStatus, errorThrown) {
delete jqXHR.then; // treat xhr as a non-promise
resolve(jqXHR);
});
});
https://github.com/kriskowal/q/wiki/Coming-from-jQuery
Hope that helps.

ajax call doesnt return the data from external JS file

I am trying to implement Repository pattern in JavaScript. I have ViewModel which i want to initialize with the data when i call Initialize method on it. Everything seems to be falling in places except that i am not able to return the data from my AJAX call. I can see that data is coming back from the ajax call but when i trying to capture the data in SomeViewModel's done function, it is null.
Can someone please point me out where i am going wrong here?
P.S: Please notice that i am not making Async call so the call chain is properly maintained.
This is how my Repository looks like:
function SomeRepository(){
this.LoadSomeData = function loadData()
{
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
return data;
},
error: ajaxFailed
});
function ajaxFailed(xmlRequest) {
alert(xmlRequest.status + ' \n\r ' +
xmlRequest.statusText + '\n\r' +
xmlRequest.responseText);
}
}
};
This is how my ViewModel looks like:
function SomeViewModel(repository){
var self = this;
var def = $.Deferred();
this.initialize = function () {
var def = $.Deferred();
$.when(repository.LoadSomeData())
.done(function (data) {
def.resolve();
});
return def;
};
}
This is how i am calling from an aspx page:
var viewModel = new SomeViewModel(new SomeRepository());
viewModel.initialize().done(alert('viewmodel initialized'));
alert(viewModel.someProperty);
I have used successfully an auxiliar variable to put the ajax result, when ajax call is inside a function (only works if ajax is async=false) and i need the function does return the ajax result. I don't know if this is the best solution.
function ajaxFunction(){
var result='';
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
result=data;
},
error: ajaxFailed
});
return result;
}
Doesn't matter that it's synchronous (though it really shouldn't be). Returning a value from inside the ajax callback will not cause the value to be returned from the containing function.
Using asynchronous ajax is generally a much better idea anyway, but that will force you to create an API that allows its clients to pass in handlers to be called when the ajax request completes. To do that, you'd give your "LoadSomeData" function a parameter. A caller would pass in a function, and your ajax "success" handler would pass on the results (or some transformation of the results; depends on what it is that you're doing) to that callback. It's the same idea as the callbacks used in the ajax call itself.

Categories

Resources