I am using jquery for ajax calls
All the calls are called immmediately on page load and we are getting the responses at almost the same time.
the issue is, the 3 calls are fired and I am getting the data, but the callback function is fired for the first call only.
the other two callbacks are not called, the callback is defined as a separate function,
If I just write an alert instead of calling the callback method, all the 3 alert message are coming
So the issue is when we write the callback method, do any one have any idea of the strange behaviour?
We tried to reorder the calls, the behaviour is similar, which ever is called first, its callback will be called, for the rest, it will not be called
var url = "/test1";
ajaxCall(url, testMethod1, false);
var url = "test2";
ajaxCall(url, testMethod2, false);
var url = "test3";
ajaxCall(url, testMethod3, false);
testMethod1:function(data){
console.log("first"+data);
},
testMethod2:function(data){
console.log("second"+data);
},
testMethod3:function(data){
console.log("thrid"+data);
}
ajaxCall is defined as jquery ajax, the issue is only the testMethod1 is called, the rest 2 are not called
Regards
Hari
Well the thing that immediately caught my eye is that the URL for test1 has a forward slash preceding test1. This means that you are using a valid link in only test1. The alerts will trigger because you are probably not trying to access the data returned (which would still work even though the ajax request fails), where as you are trying to access the data in the coded call back functions you have provided, which will obviously throw a NullPointerException or whatever the equivalent as the ajax call fails due to an incorrect URL. Therefore data never gets set and the code doesn't work.
Related
I have a javascript function as:
function triggerUpload(success, error, callback) {
var options = {
type: 'post',
success: success,
error: error
};
$("input[name=file]").change(function() {
$(this).parent().ajaxSubmit(options);
});
if (callback) {
callback();
}
}
And i use it as:
triggerUpload(function() {
applyPostAjax(postUrl);
});
It works well as: When someone clicks on a Upload the triggerUpload event occurs with applyPostAjax as its parameter assigned to callback which can be kept null as its optional.
Note: These methods were coded by someone else and i can't get them clearly. I'm a newbie to javascript.
My issues is: i pass only one argument to this function. one would think that argument would get assigned to success. How/why does it get assigned to callback? What are these success, error parameters are here for?
Please explain
The parameters success and error are callback functions (same like the parameter you decided to call "callback") that gets executed when the ajaxSubmit method either successfully transmits the form data or encounters errors.
So, in your function call, you've supplied the success callback but not the error callback or callback callback. Since your function gets executed one can assume that the ajaxSubmit operation has successfully submitted the form.
One would be 100% correct to think that the argument gets assigned to success and not to callback.
Full documentation of the jQuery Forms Plugin available here: http://malsup.com/jquery/form/
and here: https://github.com/malsup/form
Specifically, the documentation of the success callback states:
success
Callback function to be invoked after the form has been
submitted. If a 'success' callback function is provided it is invoked
after the response has been returned from the server. It is passed the
following arguments:
1.) responseText or responseXML value (depending on the value of the dataType option).
2.) statusText
3.) xhr (or the jQuery-wrapped form element if using jQuery < 1.4)
4.) jQuery-wrapped form element (or undefined if using jQuery < 1.4)
What this means is that the correct prototype of the success function should be:
triggerUpload(function(response,status,xhr,form) {
applyPostAjax(postUrl);
});
Though it's perfectly fine to supply a function with more or fewer parameters because javascript allows functions to be called by fewer or more arguments than exist in their formal declaration. So if you're interested in only the result of the upload function you can just do:
triggerUpload(function(response) {
applyPostAjax(postUrl);
});
Or if you don't care about the response from the server you can just call it like how you did.
As others said, all the three success, error and callback should be functions. However, they have different purpose:
success - called once the ajax submitting is finished successfully
error - called once there is some error in the ajax submitting
callback - called no matter what is happening with the submitting. I guess this is added just to confirm that the change handler is assigned to the input field.
In other words calling triggerUpload doesn't submit the form. You just attach a handler to the file input button. Once you change it, i.e. you choose a file the form is submitted and you get a response after that.
The code is very complex so i have simplified below in order to confirm if the behavior i am experiencing is normal or due so some other error i have made in the code.
I have two separate ajax requests that each have their own unique call back. I do not care which one completes first and one has no dependency on the other
function ajax(url, cbS){
$.ajax({
url: url,
contentType: 'application/json',
dataType: 'json',
success: function(data){
cbS(data)
},
});
}
function callbackSuccess1(data){
$('#div1').html(data)
}
function callbackSuccess2(data){
$('#div2').html(data)
}
//request#1
ajax(myapiurl+'&peram1=100', callbackSuccess1);
//request#2
ajax(myapiurl+'&peram2=200', callbackSuccess2);
The problem: Sometimes callbackSuccess1 gets the data intended for request#2 and vice versa.
It seems that which ever request completes first fires callbackSuccess1 and the second to complete fires callbackSuccess2.
I need the callback to be bound to it's specific request so that regardless of the order in which they complete each request fires it's proper callback.
OTHER INFO: My backed is django-tastypie, at this point i am thinking that tastypie is somehow messing up the response. That is the only logical conclusion, given that the javascript seems to be immutable.
The proof that this is actually occurring is that when i inspect the responce on request#1 the data objects are clearly intended for request#2...
CONCLUSION:
Thanks for confirming that 'each invocation of your ajax() function will create it's own closure'. This was what i thought was going wrong. I found the problem in my API. I was doing some funky stuff and it looks like I had a variable that was not getting trashed in time causing the API to return the wrong data if the first request took longer than the second.
The only issue I see with the code you have included is that the function argument is cbS, but you are calling cbs(data) - note the different capitalization.
Other than that, each invocation of your ajax() function will create it's own closure and have it's own arguments and those arguments will be preserved separately for the internal success callback. This is an important capability in javascript and it works. It does not get the arguments of one call confused with the callback of another as long as you are not using any global variables or state that might change during the execution of the asynchronous ajax call.
You could probably use jsonp and specify callback query parameter in URL for $.ajax
callback would be the name of javascript function which is to be invoked whenever the response is returned from server.
For more details please refer jquery doc : http://api.jquery.com/jQuery.ajax/
For theory : http://en.wikipedia.org/wiki/JSONP
This is mainly used for cross-site ajax calls.
I am creating a jquery plugin. In that am using some global variablse
$.rmtableparams.recordsCount: 0 is one of them.
I am assigned some values to this from one function inside an ajax call.
callAjax = function (surl, pselector, pi, rec) {
$.ajax({
..
success: function (data) {
$.rmtableparams.recordsCount =10;
}
});
}
But while I am trying to access $.rmtableparams.recordsCount in some other function it returns 0. But strange thing is that if i alert anything before that it will returns 10 correctly.
Ie: if my script is
alert("hi");
alert($.rmtableparams.recordsCount);
the second alert will shows 10
But if only alert($.rmtableparams.recordsCount); is there it returns 0
I was wondered with this. If any body knows the reason please help me.
The assignment $.rmtableparams.recordsCount =10; is inside the success callback of an $.ajax request. So the value isn't assigned until the ajax call is completed, and a response received. This happens fairly quickly, so while you're first alert is waiting to be closed, the ajax response is received, and the assignment is processed. Then, the second alert shows the new value.
If you leave out the first alert, the call is still being processed and the $.rmtableparams.recordsCount value hasn't changed yet.
It's as simple as that: AJAX stands for Asynchronous JavaScript And XML. Async is key, but often overlooked...
You can't just go ahead and set $.rmtableparams.recordsCount because $.rmtableparams doesn't exist.
You first need to set $.rmtableparams:
$.rmtableparams = {};
Then you go ahead and add data to the object:
$.rmtableparams.recordsCount = 10;
Make sure that the success callback is being fired. Add an alert or console.log inside the callback to do the check.
Whenever I try to find answer of this question everyone refers to ajax start/stop etc.
I am using XUI JS's XHR function for cross domain calling, now I want exactly like this
callMyXHRfunction();
callNextFunctionWhenAboveFunctionResponded();
i.e. I should move forward until unless my xhr function responds (either success or failure)
Update
Use Case:
There is a function called getAllData(), this function get all my current data submitted to server. I need to call this function often to get the latest data and move ahead. While loggin I call this function to get latest data and after every 10 mins I need to call this to get data refreshed.
So if I call each my function on success function then my code may confuse other developer and if I write like above he/she will easily know what is going on in first line and in 2nd line.
Hope now everyone understand my situation very well.
See third example on the website you are referencing:
x$( selector ).xhr( url, fn );
Second argument can be a callback, callback being the keyword you were probably looking for to begin with.
Alternatively, use a synchronous call by supplying async: false as an option.
x$("body").xhr("http://the-url",{ async: false });
Control flow will pause until the request returned and only then continue with your next function. See http://jsfiddle.net/ZQ9uw/ for reference.
You need to make the .xhr call in a way that specifies a callback function and pass in your "next" function as the callback.
So you'd write it like this:
callMyXHRFunction(nextFunctionToCall); // no parens after nextFunctionToCall!
function callMyXHRFunction(callback) {
$("something").xhr(url, {
error: callback, // so that nextFunctionToCall is called on error
callback: callback, // so that nextFunctionToCall is called on success
async: true
// add more options here
});
}
I'd like to fire a JavaScript function when AJAX returns the values of drop down items.
The scenario is:
function 1 fires -> ajax gets items from database -> the dropdown items are filles -> my javascript function is called.
Does any of you have idea how to make a handler for such event ?
As you've tagged the question with jQuery, I'll show you a jQuery solution:
$.post("someScript.php", function(data) {
/*This callback function is executed when the AJAX call returns successfully
You would do something with your dropdown items here
and then call your next function.*/
});
The various jQuery AJAX methods (post, get, load for example) all provide a way to pass a callback as an argument. The callback is executed upon a successful response from the server. Inside that callback function you can execute whatever code you need to, to deal with data which contains the response.
If you're not using jQuery, I'll assume you already have an XMLHttpRequest object. XMLHttpRequest has a property called onreadystatechange to which you can assign a function that runs when the state changes:
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
//This will be reached if the call returns successfully
}
}
The idea is the same as the jQuery method shown above.