Ajax call freeze while process request from callback function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I have created a common ajax call function for my application for optimizing code. the problem is while I call the function its freeze page. Please check below JS:
$(fuction(){
$('.btn').click(function(){
var data = getData('myaction/getinfo', []);
})
});
function getData(url, data) {
var result = "";
$.ajax({
url: url,
type: 'POST',
async: false,
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
result = res;
$('.custom-loader').fadeOut("slow");
}
});
return result;
}
While I click a button, ajax request working pretty well but loader not showing until ajax return response (unable to click until response return).
If I on async with async: true this will continue execution code which breaks functionality (Next execution depend on ajax response). Can anyone help me with this?
Thanks an advance!

The solution to asynchronous operations is callbacks (unless you use es6 async/await). This means that instead of expecting functions to return values you pass them callbacks, which are functions that take as a parameter the return value.
In your case this would look like,
$(function(){
$('.btn').click(function() {
getData('myaction/getinfo', [], function(res){
console.log(res);
});
})
});
function getData(url, data, callback) {
$.ajax({
url: url,
type: 'POST',
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
$('.custom-loader').fadeOut("slow");
callback(res);
}
});
}

You should get use to the "callback" mechanisim in Javascripts. Just call your post processing method in the "success" event handler.
$(fuction(){
$('.btn').click(function(){
getData('myaction/getinfo', []);
})
});
function postProcessing(data){
//Put your processing logic here. e.g. Populate the data on the screen control
}
function getData(url, data) {
$.ajax({
url: url,
type: 'POST',
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
$('.custom-loader').fadeOut("slow");
postProcessing(res);
}
});
}

Related

Promise and callback function in ajax, when does success take place ?

Right now I have a code like this:
$.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
});
If I am not mistaken, checkAgainstDBHelperWH is known as a callback function. The function executes once the servers sends back response for this particular HTTP /ajax request.
I want to try writing something like the one below, but I don't know what are the effects or is it even logical:
var request = $.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
})
arrayOfPromises.push(request);
$.when.apply(null, arrayOfPromises).done(function () {
//...some javascript here
});
I want to understand if the .done(function () is fired after the callback function checkAgainstDBHelperWH is completed? Or whatever I am trying to write above does not flow consistently with how ajax works?
Thanks!
I tested it, your code only work if the function(in this case, 'checkAgainstDBHelperWH') doesn't call ajax.
If you want to wait finishing the inner ajax process, use then() and return inner ajax.
var ajaxs =
$.get("xxx").then(function() {
return $.get("yyy").done(function() {
});
});
Here is the jsfiddle.
I'm not sure whether this way is general or not.

Getting Data from Ajax request displayed

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);
});

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();
});

Unable to read returned Javascript object from a different script file [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
Hey guys I have two simple JavaScript page. One holds the function that returns the object. The other read the returned object.
Unfortunately I am unable to read the returned object.
main.js
var userObj = getUserInfo('2');
console.log(userObj); //undefined
console.log(userObj.name); //undefined
globals.js
function getUserInfo(mapID){
var jqxhr = $.ajax({
url: user_url,
type: "GET",
cache: true,
dataType: "json",
statusCode: {
404: function () {
handleError404("Error 404 at getUserInfo();")
},
500: function () {
handleError500("Error 500 at getUserInfo();")
},
},
success: function (data) {
console.log(data);
var obj = {
name: data.name,
age: data.age,
weight: data.weight
}
console.log(obj); //{name:"Kanye West", age:23, weight:"450lbs"}
return obj;
}
});
}
As you can see, If I was to output the object in the function itself, I see the result. But not if I call it from the main.js page.
Any help would be greatly appreciated!
You don't return anything from getUserInfo so you shouldn't expect anything from it.
You are only returning something in the success callback function. That is is run asynchronously. It doesn't return anything for getUserInfo.
If you want to make your ajax call a separate function you can make it return a promise from $.ajax instead of using a success callback.
function getUserInfo(mapID){
return $.ajax({
url: user_url,
type: "GET",
cache: true,
dataType: "json",
statusCode: {
404: function () {
handleError404("Error 404 at getUserInfo();")
},
500: function () {
handleError500("Error 500 at getUserInfo();")
},
}
});
}
then in main.js
var promise = getUserInfo('2');
promise.done(function(userObj) {
console.log(userObj);
console.log(userObj.name);
});
You are not returning anything.
The success callback function in the $.ajax() call is invoked asynchronously, meaning it is executed after the HTTP request is done.
Also, it is a different function than getUserInfo. At this point you are just returning a value for the success function.
I will suggest using another function that will process whatever you receive in the success call. SO in your successs call you get to add a line like handleObject(obj)
You need to pass as function argument a callback or a promise.
Reason is simple. You are calling an ajax call, which will be finished after your function will end it's call. That is why you need to add a callback/promise.
function getUserInfo(mapID, callback){
var jqxhr = $.ajax({
url: user_url,
type: "GET",
cache: true,
dataType: "json",
statusCode: {
404: function () {
handleError404("Error 404 at getUserInfo();")
},
500: function () {
handleError500("Error 500 at getUserInfo();")
},
},
success: function (data) {
console.log(data);
var obj = {
name: data.name,
age: data.age,
weight: data.weight
}
callback(obj);
}
});
}
In order to execute your function you simply call:
getUserInfo(manId, function(object){
console.log('AJAX results');
});

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