Dealing with Async calls in Javascript - javascript

I've got into a small trouble here. In my document.ready function I've defined an object and that object is being populated by three different ajax calls(inside document.ready). Now I want to do a
console.log(myObject);
only when the 3 async calls have been executed completely. Please suggest a way to do this.

Using I would suggest you to create a function like this:
function onAllInformationIsReady() {
console.log(myObject);
}
function isAllInformationReady() {
// verify here if you have all the information
}
and you do something like this on your ajax calls (I'm not assuming you are using jQuery here, replace with your ajax call method)
$.ajax({
type: "POST",
url: "some.php",
data: "...n",
success: function(msg){
if(isAllInformationReady())
onAllInformationIsReady();
}
});
By the way, if you are using jQuery you can make synchronous ajax calls like this:
$.ajax({
type: "POST",
url: "some.php",
data: "...n",
async: false,
success: function(msg){
}
});

Try jQuery 1.5's new "deferred" objects:
var j1 = $.ajax(...);
var j2 = $.ajax(...);
var j3 = $.ajax(...);
j1.success(function(data) {
// do something with data
});
j2.success(function(data) {
// do something with data
});
j3.success(function(data) {
// do something with data
});
$.when(j1, j2, j3).done(function() {
console.log(myObject);
});
The three .success() functions will be called asynchronously and will populate myObject, and then the done function will only be invoked by $.when() once all three AJAX requests have been completed.

Related

jquery modular ajax call

Can someone shed a light on this, so I have multiple GET ajax calls and its only a few lines of codes but I'm basically repeating $.ajax({}) on every function.
Can I have 1 function of $.ajax({}) instead and use this on the functions so I don't need to repeat $.ajax({}) every time?
Something like this maybe but I'm sure its not right but its just a concept.
function ajaxCall(url, method) {
$.ajax({
url: url,
method: method,
success: function(){ } // however this should come in the below function
})
}
function firstCall() {
var url = 'www.urlsample.com';
var methodType = 'GET'
ajaxCall(url, methodType).success() // get the data from this function?
}
Is this somehow possible to do? its to avoid repeating ajax call for every function.
jQuery's .ajax() method returns a Promise-Wrapper.
function ajaxCall(url, method) {
// return promise
return $.ajax({
url: url,
method: method
});
}
function firstCall() {
var url = 'www.urlsample.com';
var methodType = 'GET'
ajaxCall(url, methodType).then(function( result ) {
// success handler
}, function( error ) {
// error handler
});
}

How to know when all the ajax calls in JQuery each loop are completed?

I am having an each loop in JQuery in which I trigger an ajax request. I want to display one success message after all the ajax calls are done executing.
My code goes below,
$('.container input:checked').each(function() {
json_data = $(this).parent().parent().find('.case_json').html()
$.ajax({
type: "POST",
url: "/some_action",
data: { json_data : json_data },
success: function(data) {
console.log('saved')
}
})
}).promise().done( function(){ $('#import_message').show().addClass('alert alert-success').html('Data imported successfully!') } );
But the problem with the code is my success message is getting displayed way before the ajax calls are done executing.
What am I doing wrong? Or do I need to change the way I implemented?
You need to combine usage $.map function with $.when, here is how it should look like:
$.when.apply($, $('.container input:checked').map(function() {
json_data = $(this).parent().parent().find('.case_json').html()
return $.ajax({
type: "POST",
url: "/some_action",
data: { json_data : json_data },
success: function(data) {
console.log('saved')
}
})
}))
.done( function(){
$('#import_message').show().addClass('alert alert-success').html('Data imported successfully!')
} );
Map function would create an array of deffereds, this array is passsed to $.when function, the problem is that it's doesn't support array as argument, but support any number of parameters, so we can use .apply() which take array of promises and pass to function as arguments.
I think you want to build an array of promises then use $.when.apply. There is a similar problem here: What is cleanest way to turn Array of JQuery Promises into a JQuery Promise of an Array?.

How to handle simultaneous ajax responses using single ajax method?

Method for handling ajax
function ajaxMethod(){
return $.ajax({
url: ajaxUrl,
type: "POST",
dataType: "JSONP",
jsonpCallback: ajaxCallback
});
}
Calls to this method:
dD(ajaxMethod());
aA(ajaxMethod());
bB(ajaxMethod());
cC(ajaxMethod());
aa,bb,cc,dd method have
promise.success(function (response) {
console.log(response);
});
Now aA response is coming in bB function,,bb response in cc function and as simultaneous call is coming.
Also tried using async true nothing happens.
Any suggestions?
With jsonpCallback you are telling jQuery to use a specific function name for the callback function (instead of generating a unique one), so each time you call it, you overwrite the previous function.
Just remove jsonpCallback: ajaxCallback.
While you are at it, remove type: "POST",, it is incompatible with JSONP.
I think this is what you are after.
This code is using the returned promise to wait for the result then passing the result to your other function.
ajaxMethod().success(function(response)
{
dD(response);
});
ajaxMethod().success(function(response)
{
aA(response);
});
ajaxMethod().success(function(response)
{
cC(response);
});
ajaxMethod().success(function(response)
{
dD(response);
});
Your aA, bB, cC and dD methods can now be:
function <insertname>(response)
{
console.log(response);
}
If you want your request to come in the synchronous way, then try the following :
var callBack = $.Callbacks();
callBack.add(dD(ajaxMethod()));
callBack.add(aA(ajaxMethod()));
callBack.add(bB(ajaxMethod()));
callBack.add(cC(ajaxMethod()));
callBack.fire();
the above line of code will make sure the respective ajax call would get call.

Javascript Scope Issue

I'm trying to get this function to work. I think the function is pretty self explanitory:
function FileExists(path){
var result = false;
$.ajax({
url: "http://mydomain.com/"+path,
type: "HEAD",
success:
function(){
result = true;
}
});
return result;
}
I need the anonymous function that is called upon success of the ajax post to set the variable "result" that was defined inside the FileExists function to true so that I can return that value from the FileExists function. I think I need a closure for this but they confuse the hell out of me.
Please help!
Thanks!
It's not a scoping issue, but rather because $.ajax is asynchronous, meaning that FileExists will return before $.ajax will complete. What you should be doing is to move all code that depends on result to inside the success callback.
Ajax calls are by default asynchronous, you can either use a callback function:
$.ajax({
url: "http://mydomain.com/"+path,
type: "HEAD",
success: function(){
callback(true);
}
});
Or make the call synchronously.
$.ajax({
async: false,
url: "http://mydomain.com/"+path,
...

Ajax jquery synchronous callback success

I have this function that makes an ajax call. I'm describing the problem in the last chunk of code comments.
function doop(){
var that = this;
var theold = "theold";
var thenew = "thenew";
$.ajax({
url: 'doop.php',
type: 'POST',
data: 'before=' + theold + '&after=' + thenew,
success: function(resp) {
if(resp == 1) {
$(that).siblings('.theold').html(thenew);
}
}
});
// I have some code here (out of the ajax) that **further** changes
// the .theold's html beyond what it was changed inside ajax success
// but the change depends on whether the resp (inside the success
// function) returned 1 or not, so this code out here depends on the ajax
// so it looks like I have to turn this ajax call into a sync ajax
return false;
}
Based on the problem as described in the code comments, what changes are best for this situation?
You need to set async: false for synchronous requests like this:
function doop(){
var that = this;
var theold = $(this).siblings('.theold').html();
var thenew = $(this).siblings('.thenew').val();
$.ajax({
async: false,
url: 'doop.php',
type: 'POST',
data: 'before=' + theold + '&after=' + thenew,
success: function(resp) {
if(resp == 1) {
$(that).siblings('.theold').html(thenew);
}
}
});
// some other code
return false;
}
see here for details
Either set the Ajax call to synchronous as stefita pointed out, or just move your code into the success callback. Why can't you do this? Even if it's another Ajax call it still can be done - you can nest them. With the information given by you so far (I can't see the problematic code, nor I have enough domain knowledge about your project) I don't see a problem, really.
I prefer to use callback to do the job because it achieves exactly the same result without actually making it synchronous. I use success:callback and then pass in the callback as a parameter.
function getData(callback) {
$.ajax({
url: 'register/getData',
data: "",
dataType: 'json',
success: callback
});
}
I then call this function like this:
getData(function(data){
console.log(data); //do something
});

Categories