jQuery: How do you perform a callback inside an AJAX call - javascript

I have a function with an AJAX call inside it, I need to be able to call the function and it return true if the AJAX request was successful and false if not.
I know the following doesn't work because the returns are out of scope to the exampleFunc()
function exampleFunc() {
$.ajax({
url: 'http://example.com/page',
success: function(data, textStatus, XMLHttpRequest){
return true;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
return false;
}
});
}
I Googled for a solution and believe I should be doing a callback but couldn't seems to achieve the desired outcome.
Edit: Te be more specific I require the function to return true or false because my use case currently has me doing :
if (exampleFunc()) {
// run this code
}

You can't return from something asynchronous. The callback function has to do what you want to do in a forwards direction.

Simply pass the function to your exampleFunc() and call it in your ajax success callback.
// you want this function to be run on ajax success.
function sayHello() {
alert('hello');
}
function exampleFunc(callback) {
$.ajax({
url: 'http://example.com/page',
success: function(data, textStatus, XMLHttpRequest){
if (callback && typeof callback == 'function') {
callback() // here, you call sayHello, which is passed as parameter
}
return true;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
return false;
}
});
}
exampleFun(sayHello); // start ajax

function exampleFunc() {
$.ajax({
url: 'http://example.com/page',
async: false,
success: function(data, textStatus, XMLHttpRequest){
return true;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
return false;
}
});
}
Notice async: false

$.ajax is an asynchronous call which will have a callback handler on success/error response. To work around, you need to pass a callback.
function exampleFunc(callback, errorCallback) {
$.ajax({
url: 'http://example.com/page',
success: callback,
error: errorCallback
});
}
USAGE
exampleFunc(function(data, textStatus, XMLHttpRequest) {
// do whatever you want, you have got a success response
//return true;
}, function (XMLHttpRequest, textStatus, errorThrown) {
// error occured, show some red error box
//return false;
});

This can only be done if you got a sync function like:
function exampleFunc() {
var success;
$.ajax({
async : false,
url: 'http://example.com/page',
success: function(data, textStatus, XMLHttpRequest){
success= true;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
success= false;
}
});
return success;
}
What you can do is pass a function to your function. Something like:
var hello = "Hello World";
exampleFunc(function(){
alert(hello); // Alerts Hello World on success
},
function(){
alert("FAILED"); // Alerts FAILED on error
});
And the function will look like:
function exampleFunc(success, error) {
$.ajax({
url: 'http://example.com/page',
success: success,
error: error
});
}
But you can't change the hello var inside the function and use it after the function call. Because the call's keep async.

Related

Access post data from inside ajax error function

I have the below javascript function that takes POST data and sends post request to server using Ajax
function postData(post_data) {
console.log(post_data, "----------->");
var data = post_data;
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataTpe: "json",
success: function (data) {
debugger;
},
error: function (jqXHR, textStatus, errorThrown) {
debugger;
// Can we access the post_data inside this error function ?
},
}
);
};
So what my actual point is, because of some reason the server is sending a 500 response and so the execution point is coming to error: function (jqXHR, textStatus, errorThrown, data), here I want to access post_data to display something to the user.... So can we access the post_data inside ajax error function above?
In case someone looks for a generic way to do this, here is how i did it: In case your handler functions are defined where their scope don't allow you to access some variables, you can add them to the ajax object itself in the function beforeSend. You can then retreive it in the ajax object by using this.
$.ajax({
url:'/dummyUrl',
beforeSend: function(jqXHR, plainObject){
plainObject.originalUrl = 'myValue';
},
success: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
$('#myValue').html(this.originalUrl);
},
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">waiting result</div>
<div id="myValue"></div>
function postData(post_data) {
console.log(post_data, "----------->");
// var data = post_data; // why ?
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataTpe: "json",
success: function (response) { // pay attention to args and vars naming as it makes the code easier to read
// use response
},
error: function (jqXHR, textStatus, errorThrown, data) {
// handle error
console.log(post_data); // and the magic happens
},
}
);
};
Above this issue you were having wrong key "dataType" i have modified it. Secondly, "post_data" is in your scope you can access it without any issue.
function postData(post_data) {
console.log(post_data, "----------->");
// var data = post_data; // why ?
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataType: "json",
success: function (response) { // pay attention to args and vars naming as it makes the code easier to read
// use response
},
error: function ( jqXHR jqXHR, textStatus, errorThrown) {
// post data is in your scope you can easily access it
console.log(post_data); // and the magic happens
},
}
);
};

Cannot return whole JSON object back to calling function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I am new to AJAX and I need to find a way to return an AJAX JSON response back to the calling function. Is there any way to achieve this.
My code snippet:
function requestAjaxWebService(webServiceName, method, jsonData) {
var returnData;
$.ajax({
url: webServiceName,
type: method,
data : jsonData,
dataType: "json",
success: function (data) {
returnData = data;
},
error: function(error){
returnData = "Server error";
}
});
return returnData;
}
jQuery.ajax() performs asynchronous HTTP request. Hence, you can't return its response synchronously (which your code is trying to do).
If the request succeeds, the success(data, textStatus, jqXHR) handler will get called at some point (you don't know when).
Here is one way you could modify your code:
function requestAjaxWebService(webServiceName, method, jsonData, callback) {
$.ajax({
url: webServiceName,
type: method,
data : jsonData,
dataType: "json",
success: function (data, textStatus, jqXHR) {
callback(true, data); // some method that knows what to do with the data
},
error: function(jqXHR, textStatus, errorThrown){
callback(false, errorThrown);
}
});
}
callback should be a reference to a method like:
function onData(isSuccess, dataOrError)
{
if (isSuccess) {
// do something with data
} else {
console.error(dataOrError);
}
}
Update If the settings object is needed in the callback for some reason:
function onData(isSuccess, settings, jqXHR, errorThrown)
{
if (isSuccess) {
// do something with the data:
// jqXHR.responseText or jqXHR.responseXML
} else {
// do something with error data:
// errorThrown, jqXHR.status, jqXHR.statusText, jqXHR.statusCode()
}
}
function requestAjaxWebService(webServiceName, method, jsonData, callback) {
var settings = {
url: webServiceName,
type: method,
data : jsonData,
dataType: "json"
};
settings.success = function(data, textStatus, jqXHR){
callback(true, settings, jqXHR);
};
settings.error = function(jqXHR, textStatus, errorThrown){
callback(false, settings, jqXHR, errorThrown);
};
$.ajax(settings);
}
requestAjaxWebService("name", "POST", "json", onData);
You can also use .done() and .fail() callbacks of jqxhr object instead of callbacks in settings object, as obiTheOne's answer suggests. It may look neater, but is not actually important here.
jQuery.ajax is an asynchronous function, so normally it doesn't return anything.
You can anyway return a value to the original function by setting the async option to false, but is not recommended, because a synchronous request will block the rest execution of the rest of your code until a response will be returned.
function requestAjaxWebService(webServiceName, method, onSuccess, onFail) {
var returnData;
$.ajax({
url: webServiceName,
type: method,
async: false,
data : jsonData,
dataType: "json",
success: function (data) {
returnData = data;
},
error: function(error){
returnData = "Server error";
}
});
}
take a look at this example: jsbin sync ajax example
You should instead use a callback (the standard way) to handle the response
function onSuccess (data) {
console.log(data);
}
function onFail (error) {
console.log('something went wrong');
}
function requestAjaxWebService(webServiceName, method, onSuccess, onFail) {
$.ajax({
url: webServiceName,
type: method,
data : jsonData,
dataType: "json",
success: onSuccess,
error: onError
});
}
Or you can return a Promise (a sort of async object) that will change value as soon as the request will be fullfilled
function requestPromise (webServiceName, method) {
return $.ajax({
url: webServiceName,
type: method,
data : jsonData,
dataType: "json"
});
}
requestPromise('...', 'GET').done(function (data) {
console.log(data);
});
refs:
jquery.ajax params

javascript not working in proper order if-else

I have form which validate duplicate name while saving and i have handling using webapi. the following is a sample function which calls by onclick="return validateName()" from an button click.
function validateName() {
var nam = $('#frmeditCategory input[id="Name"]').val();
var result = false;
$.ajax({
type: "POST",
url: "/Admin/CategoryName",
data: { Name: "test"},
dataType: "json",
success: function (response) {
if (response.message == true) {
alert("Category already exists.");
result = false;
alert(0);
return false;
}
else {
result = true;
alert("1");
return true;
}
},
error: function (xhr, ajaxOptions, thrownError) { alert("some error occured"); result = false; }
});
alert("2");
return false;
}
Here alert("2"); executes first and then ajax is working. I was confused so much and i dont know what im doing wrong. please help me guys!!!
alert("2") would need to be put inside of a $.ajaxs promise callback:
$.ajax({
type: "POST",
url: "/Admin/CategoryName",
data: { Name: "test"},
dataType: "json",
success: function (response) {
if (response.message == true) {
alert("Category already exists.");
result = false;
// Why are the following here, they will never get called?
// alert(0);
// return false;
} else {
// Why is this line here, you never use it?
// result = true;
alert("1");
return true;
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("some error occured");
result = false;
}
}).done(function () {
alert("2");
});
set async to false, this will execute the rest of the code after ajax call is complete
$.ajax({
type: "POST",
url: "/Admin/CategoryName",
data: { Name: "test"},
dataType: "json",
async: false,
success: function (response) {
if (response.message == true) {
alert("Category already exists.");
result = false;
alert(0);
return false;
}
else {
result = true;
alert("1");
return true;
}
},
error: function (xhr, ajaxOptions, thrownError) { alert("some error occured"); result = false; }
});
Ajax calls are by default asynchronous, meaning code execution doesn't halt waiting for the ajax call to return but instead continues and reaches your alert(2) statement long before the http request returns and your ajax callback is invoked.
You can also perform synchronous ajax calls but that is usually not a good idea as other things will freeze until the call returns.
That ajax call is an asynchronous request. What happens is that when you call the method you are starting the request. However, the request may take time to finish, until you get the data from the server, or an error occurs.
The function inside the ajax is executed when the data arrives from the server, and that is why this alert is only done after the alert("2");

Can ajaxSetup.success callback prevent ajax.complete callback from being called?

In $.ajaxSetup.success I want a general piece of code to check something and then the $.ajax.complete callback should not be called. Is this possible? Preferably by doing something in the $.ajaxSetup.success callback and not in every $.ajax.complete callback.
event.stopImmediatePropagation might work, but I don't know how to access event from success.
$.ajaxSetup({
success : function(jqXHR, textStatus, errorThrown) {
alert('this will happen');
}
});
$.ajax({
url: '/echo/json/',
type: 'POST',
complete: function () {
alert('this shouldn\'t happen');
}
});
jsFiddle: http://jsfiddle.net/z4L4z3oo/1/

Jquery $.ajax statusCode Else

In a jquery Ajax call I am currently handling statusCode of 200 and 304. But I also have "Error" defined" To catch any Errors that could come back.
If there is a validation message related we return the status code of 400 - Bad Request.
This then falls into the "Error" function before falling into the statusCode "400" function I had defined. Which means two actions happen.
Ideally I would like to not define "Error" and "Success" and only define "statusCode" But what I need is to have a "Else" so that I don't need to declare every statusCode that exists only the 2-3 I want to handle differently.
$.ajax({
type: 'POST',
contentType: "application/json",
url: "../API/Employees.svc/" + EmployeeId + "/Company/" + CompanyId,
data: jsonString,
statusCode: {
200: function () { //Employee_Company saved now updated
hideLoading();
ShowAlertMessage(SaveSuccessful, 2000);
$('#ManageEmployee').dialog('close');
},
304: function () { //Nothing to save to Employee_Company
hideLoading();
$('#ManageEmployee').dialog('close');
if (NothingToChange_Employee) {
ShowAlertMessage(NothingToUpdate, 2000);
} else {
ShowAlertMessage(SaveSuccessful, 2000);
}
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
AjaxError(XMLHttpRequest, textStatus, errorThrown);
}
});
Since the "complete" event is always fired you could simply get the status code from there and ignore the success and error functions
complete: function(e, xhr, settings){
if(e.status === 200){
}else if(e.status === 304){
}else{
}
}
This is what i'd use:
error: function (xhr, textStatus, errorThrown) {
switch (xhr.status) {
case 401:
// handle unauthorized
break;
default:
AjaxError(xhr, textStatus, errorThrown);
break;
}
}
jQuery AJAX response complete, success, error have been deprecated. More up-to-date version with .done, .fail, .always promise instead.
On success .always has signature of .done, on failure it's signature changes to that of .fail. Using the textStatus you can grab the correct variable and return the body contents.
var jqxhr = $.ajax( {
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
dataType: 'json',
} )
.done(function( data, textStatus, jqXHR ) {
alert( "success" );
})
.fail(function( jqXHR, textStatus, errorThrown ) {
alert( "error" );
})
.always(function( data_jqXHR, textStatus, jqXHR_errorThrown ) {
if (textStatus === 'success') {
var jqXHR = jqXHR_errorThrown;
} else {
var jqXHR = data_jqXHR;
}
var data = jqXHR.responseJSON;
switch (jqXHR.status) {
case 200:
case 201:
case 401:
default:
console.log(data);
break;
}
});
jqxhr.always(function() {
alert( "second complete" );
});
To keep the approach similar to your initial logic, I would continue passing a statusCode object. However, you still know that "else" will fall in the realm of 4xx or 5xx type error codes.
So I would update your original code to:
var statusCodeResponses = {
200: function () { //Employee_Company saved now updated
hideLoading();
ShowAlertMessage(SaveSuccessful, 2000);
$('#ManageEmployee').dialog('close');
},
304: function () { //Nothing to save to Employee_Company
hideLoading();
$('#ManageEmployee').dialog('close');
if (NothingToChange_Employee) {
ShowAlertMessage(NothingToUpdate, 2000);
} else {
ShowAlertMessage(SaveSuccessful, 2000);
}
}
};
var genericElseFunction = function(response){
// do whatever other action you wanted to take
};
for(var badResponseCode=400; badResponseCode<=599; badResponseCode++){
statusCodeResponses[badResponseCode] = genericElseFunction;
}
$.ajax({
type: 'POST',
contentType: "application/json",
url: "../API/Employees.svc/" + EmployeeId + "/Company/" + CompanyId,
data: jsonString,
statusCode: statusCodeResponses,
error: function (XMLHttpRequest, textStatus, errorThrown) {
AjaxError(XMLHttpRequest, textStatus, errorThrown);
}
});

Categories

Resources