returned array is undefined, not async - javascript

For some reason my function is returning undefined while seemingly working in itself.
function getDomains() {
$.ajax({
url: '/rewrites/cgi-bin/ajax.pl?action=listdomains',
dataType:'json',
async: false,
success: function( data ) {
if (data.error) {
alert(data.error);
}
else {
alert(data.domains);
return(data.domains);
}
}
});
}
alert(getDomains());
My first alert shows a populated list but the second is undefined. Does this make any sense?

You're in a function for the success call. That's why you're not getting a result from your getDomains function. Assign it to a variable and return the variable after the ajax call.
function getDomains() {
var results;
$.ajax({
url: '/rewrites/cgi-bin/ajax.pl?action=listdomains',
dataType:'json',
async: false,
success: function( data ) {
if (data.error) {
alert(data.error);
}
else {
alert(data.domains);
results = data.domains;
}
}
});
return results;
}
alert(getDomains());

Why don't you just do this, assuming you need your return for a function called whateverFunc():
function getDomains() {
$.ajax({
url: '/rewrites/cgi-bin/ajax.pl?action=listdomains',
dataType:'json',
async: false,
success: function( data ) {
if (data.error) {
alert(data.error);
}
else {
whateverFunc(data.domains);
}
}
});
}
function whateverFunc(domains){
alert(domains);
}
You can't return anything from success callback, it makes no sense.
I would like also to complain about the async:false here. Why do you need it absolutely?
You should let the call be async and manage the blocked state by yourself with some mutex or something around. In fact, you should trigger popup or whatever you need to do after you get the answer in the whateverFunc().
It's clean and you keep control on the blocking state.

Related

How to handle this with async Ajax request and callback

So this function getXmlData() get's called across the app who's main responsibility is to return xml to and save it to a variable, in this example below it is 'test'
var test = getXmlData();
function getXmlData() {
queryData(getData);
}
function getData(xml) {
if (xml) {
return xml;
}
}
function queryData(callback){
$.ajax({
url: "/echo/JSON",
type: 'POST',
success: function(xml){
callback(xml);
},
error: function(){
console.log("Error!!");
}
})
}
Now we know that here parent function will return before the callback is executed and so 'test' variable will be undefined.
I'm not sure how can I handle this situation here. I'm tied to using this structure. I basically want getXmlData to return xml that is being returned in queryData. Suggestions!?

Return value from ajax call

I'm trying to get the return bool from the ajax call, but when I run the function and save to a variable but the only thing i get is undefined.
function check(number, id){
$.ajax({
url: 'ai.php',
data: {
"func":"checkNumber",
"id":id,
"number":number
},
method: 'GET',
dataType: 'json'
}).done(function(jData) {
return jData['idFound'];
}).fail(function(jData) {
console.log(jData['idFound']);
});
}
var test = check(44444, 12);
console.log(test);
// true
// but i get an undefined value in the console.log
Depend ur file 'ai.php' is a format json? please check validate http://www.jsonlint.com
Confuse ur code data, its just 'post' and not 'get'.
You can try getjson or ajax, look a exemple:
$(document).ready(function() {
$.getJSON('http://beta.json-generator.com/api/json/get/NkmG8_zBZ', function(json) {
for (x=0; x<json.length; x++) {
console.log('getjson>'+json[x].nome);
}
});
$.ajax({
type: 'get',
url: 'http://beta.json-generator.com/api/json/get/NkmG8_zBZ',
dataType : 'json',
success: function(json) {
for (x=0; x<json.length; x++) {
console.log('ajax>'+json[x].cidade);
}
},
error: function(err) {
console.log(err);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Without playing with the code more, this looks like an asynchronous issue to me.
This line calls the async function:
var test = check(44444, 12);
but logging the result immediately after will be undefined because you can't guarantee a return value unless you are within the 'done' callback function.
The default JQuery AJAX behavior is asynchronous, but if you truly need it to be synchronous, you can set the option explicitly, although it is not considered good practice:
$.ajax({
async: false,
...
});

Looping through functions with ajax calls

I'm currently looping through a number of functions that validate particular input values. One in particular requires an ajax call to validate an address. I saw that users here on SO suggested using callbacks to return the value.
The only problem is, by the time it does retrieve the value, the function had already fired within the loop and returned an undefined value. I've been searching around and wasn't sure what the best solution would be. Do I somehow delay the loop? Do I have my function setup right in the first place? Need some serious help.
var validations = [validateUsername, validatePassword, validateAddress];
function submitForm() {
var inputs = validations.map(function(validation) {
return validation();
});
return inputs.every(function(input) {
return input === true;
}); // [true, true, undefined]
}
function validateAddress() {
function addressIsValid(callback) {
$.ajax({
type: 'POST',
url: '/address/validate',
data: $form.serialize(),
dataType: 'json',
success: function(response) {
return callback(response.Data === 200);
}
});
}
function callback(response) {
return response;
}
return addressIsValid(callback);
}
You should use Promises.
First, you should make your asynchronous functions return a Promise:
function validateAddress() {
return new Promise((resolve, reject)=> {
$.ajax({
type: 'POST',
url: '/address/validate',
data: $form.serialize(),
dataType: 'json',
success: response=> {
response.Data === 200 ? resolve() : reject();
}
});
});
}
Then rewrite your submitForm function like this:
function submitForm() {
var promises = validations.map(validation=> validation());
return Promise.all(promises)
}
Then you can use submitForm like this:
submitForm()
.then(()=> {
// form is valid
}, ()=> {
// form is invalid
})

To call an asynchronous function synchronously in javascript

we are trying to change some calls in the application from sync to async then i read the post
"Call An Asynchronous Javascript Function Synchronously"
so when i call the callThis() I am getting the output as:
"Success"
"failure"
but I need the output as
"Success"
"KATE success"
Can you guys suggest me a solution for this, not the callback or timeout but still an efficient technique when changed from sync to async
function callThis()
{
if(kate())
{
console.log("KATE success")
}
else
{
console.log("failure")
}
}
function kate()
{
$.ajax({
url: "www.google.com" (http://www.google.com),
type: 'get',
async: true,
timeout: 10000,
success: function (data) {
console.log("Success");
},
error: function () {
console.log("FAIL!!!");
}
});
}
The solution isn't to call it synchronously, but to work with the asynchronous nature of ajax
function callThis() {
kate().done(function(result) {
if ( result ) {
console.log("KATE success")
} else {
console.log("failure")
}
}).fail(function(error) {
console.log(error);
});
}
function kate() {
return $.ajax({
url: "www.google.com",
type: 'get',
async: true,
timeout: 10000
});
}
note that getting google.com will fail due to the same-origin policy
You could use the promise interface that jQuery returns (.done), like this:
function callThis() {
kate().done(function(result) {
if ( result ) {
console.log("KATE success")
} else {
console.log("failure")
}
}).fail(function(error) {
console.log(error);
});
console.log("KATE SPADE")
}
function kate() {
return $.ajax({
url: "www.google.com",
type: 'get',
async: true,
timeout: 10000
});
}
Even the asynchronous nature of ajax is now taken into account, I am still getting the output as:
KATE SPADE \n
KATE success

make this jQuery Ajax async=true with closure

I wrote this object and I run it into the page I have:
var dataPage = {
getData: function() {
return $.ajax({
url: '/my_url/',
data: {
product: 'some_product',
state: 'some_state'
},
type: 'POST',
async: true,
success: function (data) {
//console.log(data);
dataPage.results = data;
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Error:' + xhr.status);
alert(thrownError);
}
});
}
,returnData: function(){
var xhr = this.getData();
//console.log(xhr);
xhr.done(function() {
//console.log(xhr.responseText);
this.results = xhr.responseText;
$('#JSON').html(this.results);
});
}
}
var results = dataPage.returnData()
console.log(results)
It works perfectly as the attribute async set to false: the data is loaded into the div with id="JSON". The two console.log()s return the data and everything works fine.
Now I would like to switch to async: true but I don't know how to apply closure to make the function pass the resulting data correctly, avoiding the xhr.responseText to be undefined because of the asynchronous nature of the getData() call.
EDITED
I edited the code above, added the returnData() function, but the last console.log() still return undefined. Adding the .done() didn't solve the problem of taking out to the global scope the results if async: true...
Use the done() callback:
var jqXHR = dataPage.getData();
jqXHR.done(function(result) {
$('#JSON').html(result);
});

Categories