How to return value in ajax call? - javascript

I want after keyup in input if data was 0 return is false if was not false return is true. but in my try always return is true in case data === 0:
$('input').live('keyup change', function () {
var result = true;
$.ajax({
type: 'POST',
dataType: 'json',
url: 'search_customer',
data: dataObj,
cache: false,
success: function (data) {
if (data == 0) {
alert('data is 0')
result = false;
} else {
alert('data is not 0')
}
}
})
//alert(result) this output always is 'true'
return result;
})

The .ajax() call returns at an arbitrary time in the future. The keyup and change handlers return (essentially) immediately.
Do the work in your success handler. Alternatively, you could set a global (or namespaced global) to the returned value, with the understanding that it would be invalid until the Ajax call completes.
You also need to make sure the data being returned is what you expect it to be, if the if statement itself isn't doing what you expect. That's a different issue than the return value from the event handler.

I see that you've selected async: false as your answer, but there is a better way - using a callback function.
$('input').live('keyup change', function () {
DoSomething(function(result) {
// this isn't blocking
});
})
function DoSomething(callback) {
$.ajax({
type: 'POST',
dataType: 'json',
url: 'search_customer',
data: dataObj,
cache: false,
success: function (data) {
var result = data !== 0;
if (typeof callback === 'function') {
callback(result);
}
}
});
}

Related

How can a guarantee one ajax call is complete before calling another?

I am working on a flask application and there is this javascript function associated with a form
function applyQueries() {
// does some things
if(currentCatalog != ''){
addCatalogFilters(currentCatalog);
}
$.ajax({
type: 'POST',
url: "/applyQueries",
contentType: "application/json",
success:function(response){
// does some stuff here
})
}
The addCatalogFilters() function is also an ajax call. Both these calls change some variables in the python side of things. What I want to know is if the first ajax call (in addCatalogFilters), is guaranteed to execute and return before the second one. I am ending up with weird results that appear to be race conditions based on the order the ajax calls execute. Is this possible with code structured like this? Also if so, how can I fix it?
// Add user catalog filters
function addCatalogFilters() {
catalog = currentCatalog;
formData = new FormData(document.getElementById('catalogFilterForm'));
$.ajax({
type: 'POST',
url: "/addCatalogFilters",
data: formData,
processData: false,
contentType: false,
success: function (response){
document.getElementById(catalog + 'close').style.display = 'block';
document.getElementById(catalog + 'check').style.display = 'none';
addBtns = document.getElementsByClassName("addBtn");
removeBtns = document.getElementsByClassName("removeBtn");
for (i = 0; i < addBtns.length; i++) {
addBtns[i].style.display = "none";
removeBtns[i].style.display = "inline-block";
}
}
})
};
You can ensure with success function of ajax. First call a ajax (let's say ajax1) then call another ajax call within the success function of first ajax call (ajax1 success function).
addCatalogFilters(currentCatalog)
{
$.ajax({
type: 'POST',
url: "/the-post-usl",
success:function(response){
$.ajax({
type: 'POST',
url: "/applyQueries",
contentType: "application/json",
success:function(response){
// does some stuff here
});
})
}
function applyQueries() {
// does some things
if(currentCatalog != ''){
addCatalogFilters(currentCatalog);
}
}
It may not be the optimum way. But guarantee one ajax call is complete before calling another.
You could try using async/await like this:
async function applyQueries() {
if(currentCatalog !== ''){
const filtersAdded = await addCatalogFilters(currentCatalog);
}
// Perform AJAX call
}
By usinc async/await, your code will wait until the addCatalogFilters() function has resolved. However, for this to work, the addCatalogFilters() function should be async with a return value. Something like this:
async function addCatalogFilters(catalog){
// Ajax call
$.ajax({
type: 'POST',
url: "foo",
contentType: "application/json",
success:function(response){
return true
})
}
Depending on how applyQueries is called, you may need to have an await or .then where you call it. Note that you can also use "result = await addCatalogFilters(currentCatalog)" to put the ajax result into a variable result that you can work with and pass to your $.ajax call in applyQueries. I don't know the nature of your code, so I can't make any direct suggestions.
async function applyQueries() {
// does some things
if(currentCatalog != ''){
// await on the returned Promise-like jqXHR (wait for ajax request to finish)
// recommend assigning awaited result to a variable and passing to next $.ajax
await addCatalogFilters(currentCatalog);
}
return $.ajax({
type: 'POST',
url: "/applyQueries",
contentType: "application/json",
success:function(response){
// does some stuff here
})
}
// Add user catalog filters
function addCatalogFilters() {
catalog = currentCatalog;
formData = new FormData(document.getElementById('catalogFilterForm'));
// return the Promise-like jqXHR object: https://api.jquery.com/jQuery.ajax/#jqXHR
return $.ajax({
type: 'POST',
url: "/addCatalogFilters",
data: formData,
processData: false,
contentType: false,
success: function (response){
document.getElementById(catalog + 'close').style.display = 'block';
document.getElementById(catalog + 'check').style.display = 'none';
addBtns = document.getElementsByClassName("addBtn");
removeBtns = document.getElementsByClassName("removeBtn");
for (i = 0; i < addBtns.length; i++) {
addBtns[i].style.display = "none";
removeBtns[i].style.display = "inline-block";
}
}
})
};
You can use async/await. However, as no one has mentioned, I would like to demonstrate how you can accomplish this with Promise.
Lets define two functions:
function first_function(data) {
return new Promise((resolve, reject) => {
let dataSet = [[]];
let response;
$.ajax({
type: "POST",
url: 'example.com/xyz',
async: false,
data: data,
success: function (value) {
response = value;
dataSet = JSON.parse(response);
resolve(dataSet)
},
error: function (error) {
reject(error)
},
processData: false,
contentType: false
});
})
}
function second_function(data) {
return new Promise((resolve, reject) => {
let dataSet = [[]];
let response;
$.ajax({
type: "POST",
url: 'example.com/abc',
async: false,
data: data,
success: function (value) {
response = value;
dataSet = JSON.parse(response);
resolve(dataSet)
},
error: function (error) {
reject(error)
},
processData: false,
contentType: false
});
})
}
Now you can make sure that second_function() gets called only after the execution of ajax request in first_function() by following approach:
first_function(data)
.then(dataSet => {
//do other things
second_function(dataSet)
.then(dataSet2 => {
////do whatever you like with dataSet2
})
.catch(error => {
console.log(error);
});
});

How to set false to ASP Button if Ajax result is success?

I am calling Ajax when user click the button. When calling ajax it will check the data with textbox whether the textbox value is already exist or not. If exist, then it should not return false, if the record is not found in database, jquery button should return true let it to save on database through server side.
Note:
My Ajax code is working. But when I the is exist and set return false this statement is not execute.
Here is my code:
$('#btnSaveFile').click(function () {
var fileNames = $('#txtFileName').val();
var flags = 'test';
alert('test='+flags);
$.ajax({
url: 'ReportTotalSalesPivot.aspx/getFileExistOrNot',
method: 'post',
async:false,
contentType: 'application/json',
data: '{fileName:"' + fileNames + '",reportName:"TotalSales"}',
dataType: 'json',
success: function (data) {
if (data.d === 'dataExist') {
// it execute this loop, but after it execute it's going to server
$('#lblSaveErrorMsg').text('This filename already exist. Please change the name');
return false;
}
else {
return true;
}
},
error: function (error) {
alert('Please Call Administrator');
}
});
});
I found result myself.
Ajax is an Asynchronous. We cannot do return false when the result is success.
So I declare one variable outside of ajax and with the certain condition in success I set return false in outside of ajax code
This is my Jquery code
$('#btnSaveFile').click(function () {
var fileNames = $('#txtFileName').val();
var flag = 'returnTrue';
$.ajax({
url: 'ReportTotalSalesPivot.aspx/getFileExistOrNot',
method: 'post',
async: false,
contentType: 'application/json',
data: '{fileName:"' + fileNames + '",reportName:"TotalSales"}',
dataType: 'json',
success: function (data) {
if (data.d === 'dataExist') {
flag = 'returnFalse';
$('#lblSaveErrorMsg').text('This filename already exist. Please change the name');
}
else {
alert('else');
return true;
}
},
error: function (error) {
alert('Please Call Administrator');
}
});
if (flag === 'returnFalse') {
return false;
}
});

Jquery Asynchronous call return undefined value

I have gone through many topics on stack overflow for jquery asynchronous AJAX requests. Here is my code.
funciton ajaxCall(path, method, params, obj, alerter) {
var resp = '';
$.ajax({
url: path,
type: method,
data: params,
async: false,
beforeSend: function() {
$('.black_overlay').show();
},
success: function(data){
console.log(data);
resp = callbackFunction(data, obj);
if(alerter==0){
if(obj==null) {
resp=data;
} else {
obj.innerHTML=data;
}
} else {
alert(data);
}
},
error : function(error) {
console.log(error);
},
complete: function() {
removeOverlay();
},
dataType: "html"
});
return resp;
}
The problem is, when I use asyn is false, then I get the proper value of resp. But beforeSend doesn't work.
In case, I put async is true, then its beforeSend works properly, but the resp value will not return properly, Its always blank.
Is there any way to solve both problems? I would get beforeSend function and resp value both.
Thanks
Use async:false and run the function you assigned to beforeSend manually before the $.ajax call:
var resp = '';
$('.black_overlay').show();
$.ajax({
...
Either that or learn how to use callback functions with asynchronous tasks. There are many nice tutorials on the web.
Take the resp variable out from the function
Create one extra function respHasChanged()
when you get the data successfully, use the code
resp = data;respHasChanged();
You can restructure on this way, (why no use it in async way?)
function ajaxCall(path, method, params) {
return $.ajax({
url: path,
type: method,
data: params,
beforeSend: function() {
$('.black_overlay').show();
},
dataType: "html"
});
}
Call in your javascript file
ajaxCall(YOUR_PATH, YOUR_METHOD, YOUR_PARAMS)
.done(function(data) {
console.log(data);
// DO WHAT YOU WANT TO DO
if (alerter == 0 && obj !== null) {
obj.innerHTML = data;
} else {
alert(data);
}
}).fail(function(error) {
console.log(error);
}).always(function() {
removeOverlay();
});

IE not calling $.ajaxSetup

The following call works great in every browser but IE. $.ajaxSetup doesn't get recognized. The error and complete functions won't be called unless I add them directly into the $.ajax call.
Any idea why?
function setupAjaxCalls() {
$.ajaxSetup({
type: 'GET',
dataType: "jsonp",
contentType: "application/json",
data: {
deviceIdentifier: deviceIdentifier,
deviceType: deviceType,
memberId: loggedInMemberId,
authToken: authToken,
cache: false,
responseFormat: 1
},
error: function (x, e) {
defaultError(x, e);
},
complete: function () {
apiCallInProgress = 'false';
//alert('complete!');
}
});
}
function logInForm(memLogin, memPassword, callback) {
apiCallInProgress = 'true';
$.ajax({
type: 'POST',
dataType: "json",
url: baseApiUrl + '/MembershipService/AuthLoginSecure',
data: {
login: memLogin,
password: memPassword,
responseFormat: 0
},
success: function (data) {
if (data.Success == false) {
apiError(data);
} else {
loggedInMemberId = data.Member.Id;
authToken = data.Token;
if (typeof (callback) != "undefined" || callback) {
callback(data);
}
}
}
});
}
Straight from the documentation:
http://api.jquery.com/jQuery.ajaxSetup/
Note: Global callback functions should be set with their respective global Ajax event
handler methods—.ajaxStart(), .ajaxStop(), .ajaxComplete(), .ajaxError(), .ajaxSuccess(),
.ajaxSend()—rather than within the options object for $.ajaxSetup().
You should move the error and complete properties into their own methods. :) Or, you can just put them into the $.ajax method. Whatever works best for your preferred code pattern!

Promote callback onSuccess return value to the Caller Function return value

I have a javascript function that calls a generic function to make an ajax call to the server. I need to retrieve a result (true/false) from the callback function of the ajax call, but the result I get is always 'undefined'.
A super-simplified version of the generic function without all my logic would be:
function CallServer(urlController) {
$.ajax({
type: "POST",
url: urlController,
async: false,
data: $("form").serialize(),
success:
function(result) {
if (someLogic)
return true;
else
return false;
},
error:
function(errorThrown) {
return false;
}
});
}
And the function calling it would be something like:
function Next() {
var result = CallServer("/Signum/TrySave");
if (result == true) {
document.forms[0].submit();
}
}
The "result" variable is always 'undefined', and debugging it I can see that the "return true" line of the callback function is being executed.
Any ideas of why this is happening? How could I bubble the return value from the callback function to the CallServer function?
Thanks
Just in case you want to go the asynchronous way (which is a better solution because it will not freeze your browser while doing the request), here is the code:
function CallServer(urlController, callback) {
$.ajax({
type: "POST",
url: urlController,
async: true,
data: $("form").serialize(),
success:
function(result) {
var ret = ( someLogic );
callback(ret);
},
error:
function(errorThrown) {
return false;
}
});
}
function Next() {
CallServer("/Signum/TrySave", function(result) {
if (result == true) {
document.forms[0].submit();
}
});
}
I usually put any code to be executed on success inside the callback function itself. I don't think CallServer() actually receives the return values from the callbacks themselves.
Try something like:
function CallServer(urlController) {
$.ajax({
type: "POST",
url: urlController,
async: false,
data: $("form").serialize(),
success:
function(result) {
if (someLogic)
document.forms[0].submit();
else
// do something else
},
error:
function(errorThrown) {
// handle error
}
});
}
Edit: I'm not too familiar with jQuery, so I might be completely wrong (I'm basing this on the behavior of other frameworks, like YUI, and AJAX calls made without any framework). If so, just downvote this answer and leave a comment, and I will delete this answer.
Just found how to do it :) Declaring a variable and updating it accordingly from the callback function. Afterwards I can return that variable. I place the code for future readers:
function CallServer(urlController) {
var returnValue = false;
$.ajax({
type: "POST",
url: urlController,
async: false,
data: $("form").serialize(),
success:
function(result) {
if (someLogic){
returnValue = true;
return;
}
},
error:
function(errorThrown) {
alert("Error occured: " + errorThrown);
}
});
return returnValue;
}

Categories

Resources