I am calling two function on change event.
function1();
function2();
function1() : is a ajax call
function2() : is getting executed before function1().
Why is this happening?
Any help?
The first A of Ajax means asynchronous, i.e. the regular Javascript program flow will continue while the Ajax request is still being processed. Therefore, function2 will be executed before the Ajax request initiated from function1 will be finished.
Solution: Every asynchronous method in Javascript will provide you with a so-called callback, which is a function that will be called after the asynchronous method finished. In jQuery.ajax() this callback is provided with the parameter success. If you put the call to function2 inside this callback, it will work.
function1() {
...
$.ajax({
url: '...',
type: 'GET',
success: function(data) {
// this will be executed after the asynchronous method finishes
function2();
}
});
}
Please look at the code written below:
function1() {
$.ajax({
url: myurl,
type: 'GET',
async:false,
success: function(response) {
function2();
}
});
}
Please note here the "async:false" will ensure that the success method will call when the first function has been successfully executed. So you should use "async:false" to ensure that the function2() will call after function1().
Call your function2 after successful response from Ajax.
function function1()
{
//Ajax Call
..
..
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
function2();
}
}
if function1() is ajax function then call function2() on the success of your ajax
if you are using jquery ajax
function1() {
$.ajax({
url: myurl,
type: 'GET',
success: function(response) {
function2();
}
});
}
Normally Call like this
function1(function() {
function2();
});
If it is Ajax call like this
function function1() {
$.ajax({
url: "url",
type: 'POST',
}).success(function (html) {
function2();
});
}
Fiddle
jQuery ajax returns deferred object (http://api.jquery.com/category/deferred-object/), its really usefull for things like yours. By the way, deferred object support chaining pattern, so you can call more than one function.
So, to run one function after another you can do next
function ajaxCall(){
return $.get('your/api/call', {param:1});
}
function fun1(){
console.log('Function 1 was called');
}
function fun2(){
console.log('Function 2 was called');
}
ajaxCall().done(fun1).done(fun2);
Or you can use $.when
$.when( $.get('your/api/call') )
.then(function(){ alert(1); })
.then(function(){ alert(2); });
Usefull links:
jQuery ajax
jQuery when
jQuery deferred
Related
I'm not so much pro in javascript variable scopes and got stuck with one question.
If i have function which dose ajax call and then call my callback
function doAjaxFunc(param, callback)
{
$.ajax({
type: 'GET',
url: '/some/url/'+param,
success: function(data){
callback(data);
},
dataType:'json'
});
}
function someCallback1(ajaxResp){
// DO someting 1
}
function someCallback2(ajaxResp){
// DO someting 2
}
// exec
doAjaxFunc(1, someCallback1);
doAjaxFunc(2, someCallback2);
As ajax is async and it can be that sever will process param=1 case longer then param=2 is it possible that someCallback1 and someCallback2 will process not their responses. I mean callback argument value will be somehow mixed ?
If possible give some explanation details in answer
I mean callback argument value will be somehow mixed?
No. The callbacks will be called in completely separate invocations within scope of the originating AJAX success handler. There will be no cross-contamination of the data from either request.
Also, just as an aside, you can change this:
success: function(data){
callback(data);
},
To just this:
success: callback,
Check this example , i hope it is some helpful to understand scope in JavaScript
var isFirstCall=false;
function doAjax(param)
{
if(!isFirstCall)
{
//for example after do ajax
var millisecondsToWait = 1000;
setTimeout(function() {
console.log(param);
}, millisecondsToWait);
}
isFirstCall=true;
console.log(param);
}
doAjax('first call');
doAjax('second call');
Im trying to add an optional callback inside an AJAX successful execution, but I can't seem to get the callback to run when I want it to.
heres and example of my AJAX code
function someAjaxFunction(hosturl, callback){
$.ajax({
type: "GET",
url: hosturl,
data: {'something': 'code' },
dataType: 'json',
success: function(html){
var arr = $.map(html, function(val) { return val; });
if(arr[0] != 'false'){
console.log('1');
console.log('2');
if (callback) {
console.log('calling the callback')
callback();
}
console.log('3');
}else{
console.log('fail')
}
}
});
}
here is the callback and example of how the AJAX is being executed
function thisIsACallBack(){
console.log("i'm a callback");
}
someAjaxFunction("some url", thisIsACallBack);
If I run this code the console outputs.
1
2
3
i'm a callback
I can even remove the callback if-condition all together and I would still get the same output.
Also is here a better way to handle my Ajax return currently my response wrapped inside a json object. If the database can't find the object I have to place 'false' inside an array and convert it to a json object before echoing it back to ajax.
Couse you have to pass your callback as string to your function
someAjaxFunction("some url", thisIsACallBack); // <-- Wrong thisIsACallBack will be triggered after someAjaxFunction as some separate function call
like this
someAjaxFunction("some url", "thisIsACallBack()"); // <- Correct way
// Then call eval( callback ); inside Ajax success
....
success: function(html){
...
eval( callback );
}
your problem was that in case of this code someAjaxFunction("some url", thisIsACallBack); it was triggering someAjaxFunction then thisIsACallBack function as you written someAjaxFunction name not as string
UPDATE
if you have to pass params to your callback your option is
someAjaxFunction("some url", function(param1){
thisIsACallBack(param1)
); } );
...
success: function(html){
...
callback( yourArray );
}
JavaScript has many ways how you can pass callbacks depends on your need
I have a for loop in java script :
for(i=1;i<=10;i++){
$.ajax({
type: "GET",
url: "insert_names.php",
success: function (data) {
// some codes
}
});
}
this script send all of ajax request Simultaneously !
But It makes problem for me ...
how can i can prevent continue for loop when ajax is working ?
If you need the requests to be executed in serial instead of parallel, you can do that with a little re-structuring. Don't make the AJAX requests synchronous, just use the response of each request to invoke the next one.
Consider a structure like this:
function sendRequest() {
$.ajax({
type: "GET",
url: "insert_names.php",
success: function (data) {
// some codes
}
});
}
Now the request is wrapped in a function that you can invoke. So invoke it in response to the previous request:
function sendRequest() {
$.ajax({
type: "GET",
url: "insert_names.php",
success: function (data) {
// some codes
sendRequest();
}
});
}
It's starting to look like a standard recursive pattern, so all you need now is a terminating condition. Similar to the original loop, just use an incrementing value:
var i = 1;
function sendRequest() {
$.ajax({
type: "GET",
url: "insert_names.php",
success: function (data) {
// some codes
i++;
if (i <= 10) {
sendRequest();
}
}
});
}
Then just invoke it once to start it:
sendRequest();
Now the request should be invoked 10 times as expected (unless my math is off by one, but that should be easy to correct), each request happening in response to the previous request.
With asynchronous programming, don't try to make it synchronous. Instead, perform actions in response to the callbacks.
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.
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,
...