I'm trying to make global ajax handler. so first let me show you the function
var data = {
test : 1
}
$.when( $.ajax({
type: 'POST',
url: ajaxurl,
data : data,
dataType: "json",
success: function(data) {
console.log('first me')
}
})
).then(function( data, textStatus, jqXHR ) {
console.log('then me')
});
this way it works.
and outputs
first me
then me
But I want this ajax to be a function
So this is how I'm trying to make it.
var data = {
test : 1
}
$.when(globalAjax(data)).then(function( data, textStatus, jqXHR ) {
console.log('then me')
});
function globalAjax(data) {
$.ajax({
type: 'POST',
url: ajaxurl,
data : data,
dataType: "json",
success: function(data) {
console.log('first me')
}
})
}
this way console outputs then me and then first me.
How to ask to wait ajax inside a function?
You need to return a promise in globalAjax:
function globalAjax(data) {
return $.ajax({
type: 'POST',
url: ajaxurl,
data : data,
dataType: "json",
success: function(data) {
console.log('first me')
}
});
}
And you don't need to use the $.when function:
globalAjax(data).then(function(data, ...) { ... });
$.when is, mainly, to wait for the completion of two or more deferreds or promises.
function globalAjax(data) {
return $.ajax({
type: 'POST',
url: ajaxurl,
data : data,
dataType: "json",
success: function(data) {
console.log('first me')
}
});
}
you need to return a promise from your function.
$.ajax({
type: 'POST',
url: ajaxurl,
data : data,
dataType: "json",
success: function(data) {
console.log('first me')
}
}).then(function( data, textStatus, jqXHR ) {
console.log('then me')
});
You dont need when $.ajax already returns a promise.
You need to return the ajax promise from globalAjax so that it can be passed to $.when
function globalAjax(data) {
return $.ajax({
type: 'POST',
url: ajaxurl,
data: data,
dataType: "json",
success: function (data) {
console.log('first me')
}
})
}
Demo: Problem, Solution
$.when()
If a single argument is passed to jQuery.when and it is not a Deferred
or a Promise, it will be treated as a resolved Deferred and any
doneCallbacks attached will be executed immediately.
In your case since there is no return from the method, it will pass undefined to $.when which is causing the behavior
since a promise is returned there is no need to use $.when()
globalAjax(data).then(function (data, textStatus, jqXHR) {
console.log('then me')
});
Demo: Fiddle
Related
So I need two ajax calls to get all the data. I am using jQuery's ajax call to achieve that. But then I am a bit confused at the execution order. Here is my problematic code:
$.ajax({
type: "GET",
url: "/api/data",
dataType: "json"
}).then(function (data) {
console.log("I am the first")//correct
}).then(function () {
//second ajax
$.ajax({
type: "GET",
url: "/api/lifecyclephase",
dataType: "json"
}).then(function (data) {
console.log("I am the second")//third
})
}).then(function () {
console.log("I am the third")//second
})
The output is
I am the first
I am the third
I am the second
Should not the thenwait for the second ajax to finish its job before proceeding?
The correct one:
$.ajax({
type: "GET",
url: "/api/data",
dataType: "json"
}).then(function (data) {
console.log("I am the first")
}).then(function () {
$.ajax({
type: "GET",
url: "/api/lifecyclephase",
dataType: "json"
}).then(function () {
console.log("I am the second")
}).then(function(){
console.log("I am the third")
})
})
In the problematic code, you are simply missing a return.
$.ajax({
type: "GET",
url: "/api/data",
dataType: "json"
}).then(function (data) {
console.log("I am the first");
}).then(function () {
return $.ajax({
^^^^^^
type: "GET",
url: "/api/lifecyclephase",
dataType: "json"
}).then(function (data) {
console.log("I am the second");
});
}).then(function () {
console.log("I am the third");
});
Without the return, there's nothing to inform the outer promise chain of the inner promise's exitence, hence the outer chain does not wait for the inner promise to settle before proceeding to the third stage.
The "second" $.ajax is initialized within the second .then, but that $.ajax isn't chained with anything else - the interpreter initializes the request and that's it, so when the end of the second .then is reached, the next .then (the third) executes immediately.
Try returning the second Promise instead - a subsequent .then will only wait for a Promise to resolve if that Promise is returned by the previous .then:
.then(function (data) {
console.log("I am the first")//correct
})
.then(function () {
//second ajax
return $.ajax({
// ...
I've already read this article How do I return the response from an asynchronous call? However I couldn't come up with a solution.
I'm doing an ajax request
function getdata(url)
{
console.log('Started');
jQuery.ajax({
type: "GET",
url: "http://myserver.com/myscript.php",
dataType: "json",
error: function (xhr) {
console.log('Error',xhr.status);
},
success: function (response) {
console.log('Success',response);
}
});
}
And Console displays everything fine but when I say
var chinese = getdata();
to get the data. I keep getting:
Uncaught TypeError: Cannot read property 'length' of undefined error for this line
var text = chinese[Math.floor(Math.random()*chinese.length)];
Can anybody help me here?
The problem is that you are using an asynchronous method expecting a synchronous result.
Therefore you should use the code in the result of the asynchronous call like the following:
function getdata(url) {
console.log('Started');
jQuery.ajax({
type: 'GET',
url: url,
dataType: 'json',
error: function(xhr) {
console.log('Error', xhr.status);
},
success: function(chinese) {
var text = chinese[Math.floor(Math.random()*chinese.length)];
// Do something else with text
}
});
}
getData('http://myserver.com/myscript.php');
I hope it helps :)
The error you get is because of the asynchronous nature of the call. I suggest you to assign the value after you get the success response from the API like below.
var chinese = getdata();
Then the function getdata() will be like
function getdata(url)
{
console.log('Started');
jQuery.ajax({
type: "GET",
url: "http://myserver.com/myscript.php",
dataType: "json",
error: function (xhr) {
console.log('Error',xhr.status);
},
success: function (response) {
initChinese(response.data);
}
});
}
And create a function initChinese() like
var text;
function initChinese(chinese){
text = chinese[Math.floor(Math.random()*chinese.length)];
}
You can also declare the text variable in global scope and then assign the value to text variable inside the success function without having to create a new function initChinese.
The problem is your getdata function does not return anything. In your getdata function you're doing a ajax request, which is an asynchronous request. So the data you're requesting won't, and can't be returned with your getdata function.
But you will have the requested data in your success function:
function getdata(url)
{
console.log('Started');
jQuery.ajax({
type: "GET",
url: "http://myserver.com/myscript.php",
dataType: "json",
error: function (xhr) {
console.log('Error',xhr.status);
},
success: function (response) {
console.log('Success',response);
var text = response[Math.floor(Math.random()*response.length)];
}
});
}
As I'm not able to test your code, you've to debug the rest on your own. But the response variable will be most likely your "chinese" variable.
You could try using callbacks or you could look at Promises.
The idea with callbacks is that you pass a function that is run after the ajax request is finished. That callback can accept a parameter, in this case the response.
Using callbacks:
function getData(url, successCallback, errorCallback) {
console.log('Started');
jQuery.ajax({
type: "GET",
url: url,
dataType: "json",
error: function(xhr) {
errorCallback(xhr.status);
},
success: function(response) {
successCallback(response);
}
});
}
var chinese;
getData("http://myserver.com/myscript.php", function(response) {
chinese = response; // you can assign the response to the variable here.
}, function(statusCode) {
console.error(statusCode);
});
Using Promises (< IE11 doesn't support this):
function getData(url) {
return new Promise(function(resolve, reject) {
console.log('Started');
jQuery.ajax({
type: "GET",
url: url,
dataType: "json",
error: function(xhr) {
reject(xhr.status);
},
success: function(response) {
resolve(response);
}
});
});
}
var chinese;
getData("http://myserver.com/myscript.php").then(function(response) {
chinese = response;
console.log(chinese);
}, function(statusCode) {
console.error(statusCode);
});
I think it is simple question. I've tried to search but still not found an answer yet.
deleteComment: function (commentJson, success, error) {
$.ajax({
type: "POST",
async: false,
url: deleteCommentConfig.url,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ commentId: commentJson.CommentId }),
dataType: "json",
success: function (result) {
if (result.d) {
success();
}
messageBox(result.d);
},
error: error
});
},
var messageBox = function (hasDeleted) {
if (hasDeleted) {
alert("Deleted successfully");
} else {
alert("Error");
}
}
I want to show message after success() performed.
That means the comment left already then show message.
Thanks anyway!
P/s: I read a topic about jQuery Callback Functions at https://www.w3schools.com/jquery/jquery_callback.asp.
Can we use it in here? If we can, how to use?
You can try like this
deleteComment: function (commentJson, success, error) {
$.ajax({
type: "POST",
async: false,
url: deleteCommentConfig.url,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ commentId: commentJson.CommentId }),
dataType: "json",
success: function (result) {
if (result.d) {
success();
}
$.when(this).then(setTimeout(function(){ messageBox(result.d)}, 200));
// if you dont want use set timeout then use
// $.when(this).then(messageBox(result.d), 200));
},
error: error
});
},
var messageBox = function (hasDeleted) {
if (hasDeleted) {
alert("Deleted successfully");
} else {
alert("Error");
}
}
Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.
Considering your implementation of var success = function() you may try with following approach:
Modify the success() to accept callback function as follows:
var success = function(callback) {
self.removeComment(commentId);
if(parentId)
self.reRenderCommentActionBar(parentId);
if(typeof callback == "function")
callback();
};
var messageBox = function (hasDeleted) {
if (hasDeleted) {
alert("Deleted successfully");
} else {
alert("Error");
}
}
deleteComment: function (commentJson, success, error) {
$.ajax({
type: "POST",
async: false,
url: deleteCommentConfig.url,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ commentId: commentJson.CommentId }),
dataType: "json",
success: function (result) {
if (result.d) {
//passing the callback function to success function
success(function(){
messageBox(result.d);
});
}
},
error: error
});
},
Below, am making an AJAX call. First it has to hit the dofirstthing.do. On success of it, it has to make a call with "param1" as the query parameter.
My question - I need to make another call with "param2" as the query parameter after above call. Not sure how to?
$.ajax({
url: "dofirstthing.do",
jsonp: false,
type: "GET",
dataType: "JSON",
statusCode: {
200: function () {
global.location.search = param1;
}
}
});
You can chain the ajax calls like this
$.ajax({..}).then(function(data1){
return $.ajax({..});
}).then(function(data2){
return $.ajax({..});
})
You can execute a function on success or fail as this:
var jqxhr = $.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
reference:
http://api.jquery.com/jquery.ajax/
jQuery offers a $.get() function that returns a promise.
You can chain your requests.
see https://api.jquery.com/deferred.then/ for more info
Try using jQuery deferred.then() , defining an error function
var err = function err(jqxhr, textStatus, errorThrown) {
console.log(errorThrown)
}
$.ajax({
url: "dofirstthing.do",
jsonp: false,
type: "GET",
dataType: "JSON",
statusCode: {
200: function() {
global.location.search = param1;
$.get("/url?" + "param1=" + global.location.search)
.then(function() {
$.get("/url?" + "param2=" + param2).then(null, err)
}, err)
}
}
});
You can do it with a chain of callbacks ---
function sendAjax(target,callback)
{
$.ajax({
url: target,
jsonp: false,
type: "GET",
dataType: "JSON",
statusCode: {
200: callback
}
});
}
Now call Your function as -
sendAjax("dofirstthing.do",function(data){
sendAjax("dofirstthing.do?param1="+data,function(data){
sendAjax("dofirstthing.do?param2="+data,function(data){
return ;
});
});
});
I have a Jquery ajax function
t.doPostCall=function(url,data,ResponseHandler){
$.ajax({
type: "POST",
url: url,
data:data,
success: function(response){
ResponseHandler(response);
},
error:function(response){
ResponseHandler(response.responseJSON);
},
dataType: "json"
});
};
I want to pass parameter to ResponseHandler(response,function(){}) and execute that function depending on response.
ResponseHandler(response,fn){
if(response.check!=null){
fn();
}
}
Is it possible to do this without adding the fn to doPostCall.