I've got a custom function, which calls ajax request and I'm able to save response data to variable and return it. 0 is always returned, but alert shows e.g. 3712.
Here is the function:
function getNo(index, val) {
var $ret = 0;
$('body').showLoading();
$.ajax({
type: 'POST',
url: BASE_URL + 'tools/no.php?id='+index+'&value='+val,
data: $("#form").serialize(),
cache: false,
success: function(data) {
$('body').hideLoading();
alert('data: ' + data);
$ret = data;
}
});
return $ret;
}
because ajax is asynchronous, when return $ret; is executed, the response is not ready yet, so its initial value 0 is returned.
you have to do what you want to do in the success callback function rather than return.
This will return ZERO because of the asynchronous call. Rather I would suggest you to pass a callback method to work with the response.
See an example below:
function getNo(index, val, callback) {
var $ret = 0;
$('body').showLoading();
$.ajax({
type: 'POST',
url: BASE_URL + 'tools/no.php?id=' + index + '&value=' + val,
data: $("#form").serialize(),
cache: false,
success: function (data) {
$('body').hideLoading();
callback(data);
}
});
return $ret;
}
//USAGE
getNo(3, "value", function (data) {
//do something with data responded from the server
alert(data);
});
Because "A" in Ajax stands for Asynchronous, return $ret; is executed before the Ajax call finds it's way back to success function.
Rather than trying to return the value, try to call a function within the ajax success block.
success: function(data) {
$('body').hideLoading();
alert('data: ' + data);
$ret = data;
doSomething(data);
}
Related
I have looking for the solution with my case. In other question variable from ajax success will execute like this:
$.ajax({
...,
success: function(data) {
myFunction(data);
});
myFunction(data){
// process the data here ..
}
But in my case I call another ajax(2) with ajax(1). And really need that variable from ajax(2) to ajax(1) for process. My code look like this:
$("#formVerify").submit(function(event) {
$.ajax({
....
success: function(data){
var result= call_id(data.id);
console.log(result);
}
});
});
function call_id(data) {
var output = null;
$.ajax({
....
success: function(result){
output = result;
}
});
return output;
}
the result will always null because I set output to, or sometimes it is undefined if I don't set the value to null. I tried async: false but in my machine it wouldn't work. Need help thank you
Remember Ajax call doesn't return result, you can't use return statement in ajax call. You can get the result only using callback/promises.
Change you first ajax call to pass the callback instead of trying to get the return value:
$("#formVerify").submit(function(event) {
$.ajax({
....
success: function(data){
call_id(data.id, function(result){
console.log(result);
});
}
});
});
and change your second ajax call_id function to take callback as parameter like this:
function call_id(data, callback) {
$.ajax({
....
success: callback
});
}
I have an array of ids, and I need to send each id with separate AJAX request. But each next id in the array needs to be sent only after AJAX received a success response from the server for the previuse request.
var idsArrays = [2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 ];
$.each(idsArrays, function( index, value ) {
var data = "id="+value;
$.ajax({
type: 'POST',
url: formRequiredAction,
data: data,
dataType: 'json',
success: function(resp){
console.log('success ' + resp);
},
error: function(resp){
console.log('error ' + resp);
},
});
});
How can I set pause or wait time for next iteration until ajax will receive success response from the server?
Just make your ajax sychronous and check with a variable if the call has succeeded. EDIT: Forgot it was an .each so break wont work. Just use return.
$.each(idsArrays, function( index, value ) {
var data = "id="+value;
var success = true;
$.ajax({
type: 'POST',
url: formRequiredAction,
data: data,
dataType: 'json',
success: function(resp){
console.log('success ' + resp);
},
error: function(resp){
console.log('error ' + resp);
success = false;
},
async: false
});
if(!success){
return false;
}
});
To chain all the ajax request without locking the browser with synchronous requests you can use promises.
In the example below I use Array.reduce() to digest the list one by one and get the reference of the previous promise. $.when() is used to create the first resolved promise to kick things off. asyncAction() is used to mirror an async operation.
var idsArrays = [2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 ];
idsArrays.reduce(function(lastPromise, id, index){
var deferred = $.Deferred();
lastPromise.then(function(){
asyncAction(id, deferred.resolve.bind(deferred))
});
return deferred.promise();
}, $.when()).then(function(){
console.log('All Done!');
});
function asyncAction(id, done){
setTimeout(function(){
console.log('Sent', id);
done();
}, 250);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
You can replace asyncAction() with your ajax call, just make sure to resolve the promise calling deferred.resolve() within your ajax success callback. Do note that any failing ajax request will break the chain.
I've been trying to figure this one out since my earlier question.
I can receive the data, as I see it under resources using Develop > Show Web Inspector on safari. But I can't seem to assign it successfully to a variable to use later on.
<script>
function getData () {
$.ajax
({
type: "GET",
url: "https://myjirasite.com/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
//async: true,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (){
//Attempt 1 at outputting the result to an alert.
alert(JSON.parse(data));
}
});
}
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
</script>
In a second attempt I assign the ajax call to a variable and attempt to print that out to an alert. No success. the alert is empty
var jqXHR = $.ajax
({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
async: false,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (data){
alert(JSON.parse(data));
}
});
alert(JSON.parse(jqXHR.responseText));
I know that the issue lies with ajax calls being asynchronous, but I can't figure out how to write the callback such that I can get the json data into a variable to use later in via a different function.
Don't set async: false, as this will block the browser whilst your Ajax request is processed.
Instead, you can use promises, or call a further function from within your success callback.
Something like:
function getData(){
return $.ajax({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));
}
});
}
getData()
.done(function (data){
console.log(JSON.parse(data));
})
.fail(function(){
console.log("Error!");
});
<script>
var getData = function() {
$.ajax
({
type: "GET",
url: "https://myjirasite.com/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
//async: true,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (){
//Attempt 1 at outputting the result to an alert.
alert(JSON.parse(data));
getData.data= JSON.parse(data);
}
});
}
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
setTimeout(function(){console.log(getData.data);}, 3000); // Fire after 3 seconds to get data.
</script>
I don't think $.ajax actually returns anything - but I could be wrong. Either way, that's not too important, because you shouldn't rely on the results of an ajax call being available immediately. Your alert statement is firing before the Ajax request is finished - it sounds like you know that already.
When leveraging asynchronous calls (ajax), its a best practice to have any logic that relies on the data returned from the call to be done in (or triggered by) a callback (or as #Jack Zelig mentions, promises). This is what success parameter of $.ajax is all about. It will get called once the request completes successfully. You can also define complete and error callbacks - which fire once the request is complete (regardless of status) and once the request fails respectively.
So to summarize, your best option is probably this:
var jqXHR = $.ajax
({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
success: successHandler
});
function successHandler(data) {
alert(JSON.parse(data));
}
In this way, only once data is received will an alert be shown that will contain the data.
I have a jquery ajax code as following:
$(document).ready(function() {
var global_arr = new Array();
$.ajax({
url: 'result.php',
type: 'post',
dataType: 'json',
success: function(data) {
$.each(data, function(key, value) {
global_arr.push(value.name);
});
alert(global_arr); //get correct value, works fine
}
}); //end of ajax function
alert(global_arr); //get null, it doesn't work properly
});
Notice the lines to alert global_arr, why I can't get the value out of $.ajax() function?
Thanks anyone help on this.
Ajax takes time to complete. The function execution does not take nearly as much time. So by the time you get to your alert outside of the ajax request, the ajax request is still using time to complete (either in transmission or in server side actions).
You can always wait for the ajax method to be complete.
$(document).ready(function() {
var global_arr = new Array();
var complete = false;//flag to wait for ajax completion
$.ajax({
url: 'result.php',
type: 'post',
dataType: 'json',
success: function(data) {
$.each(data, function(key, value) {
global_arr.push(value.name);
});
alert(global_arr); //get correct value, works fine
complete = true;//mark ajax as complete
}
}); //end of ajax function
(function runOnComplete(){
if( complete ){//run when ajax completes and flag is true
alert(global_arr);
}else{
setTimeout(runOnComplete,25);//when ajax is not complete then loop
}
})()
});
However, the most common way is to use a callback.
$(document).ready(function() {
function runOnComplete(){//code executes once ajax request is successful
alert(global_arr);
}
var global_arr = new Array();
$.ajax({
url: 'result.php',
type: 'post',
dataType: 'json',
success: function(data) {
$.each(data, function(key, value) {
global_arr.push(value.name);
});
alert(global_arr); //get correct value, works fine
runOnComplete();//callback
}
}); //end of ajax function
});
Ajax is asynchronous. At the time the JS engine reaches your non-functioning alert() line, the AJAX call has not yet had a chance to get a response from the server and set the variable.
That's why the inner alert() works. It gets executed when the response comes in from the server.
Ajax function runs asynchronously and before ajax function adds incoming data in your array, the outer alert function runs and for this reason alerts an empty array.
You can use async-await to make the outer alert function wait for the incoming data.
$(document).ready(async function() {
var global_arr = new Array();
await $.ajax({
url: 'result.php',
type: 'post',
dataType: 'json',
success: function(data) {
$.each(data, function(key, value) {
global_arr.push(value.name);
});
alert(global_arr);
}
}); //end of ajax function
alert(global_arr); //it will work fine now
});
that is because alert(global_arr); //get null, it doesn't work properly runs before $.ajax has completed
My suggestion here would be to break this out in to 3 funcitons so it will make a bit more sense. You will need ajax, handelRequest, onComplete.
You may also want to add and error handler to your ajax function so if it does fail it can do so with out the script locking up on the user.
$(document).ready(function () {
var global_arr = new Array();
$.ajax({
url: 'result.php',
type: 'post',
dataType: 'json',
success: handelRequest(data),
error: handleError
});
function handelRequest(data) {
$.each(data, function (key, value) {
global_arr.push(value.name);
});
onComplete(global_arr); //get correct value, works fine
}
function onComplete(global_arr){
// then here you can do what ever you
// you would like with the array
alert(global_arr);
}
function handleError(){
// gracefully fail
}
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
function ajax_test(str1){
var url = "None"
jq.ajax({
type:'post',
cache: false,
url: 'http://....' + str1,
success: function(data, status, xhr){
url=data;
},
error: function (xhr, status, e) {
},
async: true,
dataType: 'json'
});
return url
}
How can I set the global variable url to be the returned success ajax data?
In Javascript, it is impossible for a function to return an asynchronous result. The function will usually return before the AJAX request is even made.
You can always force your request to be syncronous with async: false, but that's usually not a good idea because it will cause the browser to lock up while it waits for the results.
The standard way to get around this is by using a callback function.
function ajax_test(str1, callback){
jq.ajax({
//... your options
success: function(data, status, xhr){
callback(data);
}
});
}
and then you can call it like this:
ajax_test("str", function(url) {
//do something with url
});
Here is my example code for retrieving data from php, and then pass the value to a javascript global variable within ajax success function. It works for me!
var retVal = null;
function ajaxCallBack(retString){
retVal = retString;
}
function readString(filename){
$.ajax({
type: "POST",
url: "readString.php",
data: { 'fn': filename },
success: function(response){
ajaxCallBack(response);
}
});
}
PHP code (readString.php):
<?php
$fn = $_POST['fn'];
$file = fopen("path/".$fn.".record","r");
$string = fread($file,filesize("path/".$fn.".record"));
fclose($file);
echo $string;
?>
However, as $.ajax() sent requests asynchronously, which means it may return before the success callback runs, you should not rely on it runs sequentially and return the value by itself. Therefore, here we assign php response value to global value in callback function.