Reputation: 1523
I have this code below, and I want to return the data in the success function of the ajax call. Of course, if I do async:false and return it directly I get it but I don't want to do that.
If I just run it like it is now, information variable is undefined (if I do async:false, it gets the information, so it isn't the contents of the data that is the issue).
I just don't understand why it isn't working, I googled callback functions and it appears that I am doing it right...
function PUT_updateSystem(id) {
var system= {};
system= getSystemInformation(name, function(data){
var system = data;
return system;});
var information = system.info;
}
// Returns system information
function getSystemInformation(name,callback){
$.ajax({
type:"GET",
url: getUrl(),
cache: false,
dataType: "json",
success: function(data){
callback(data);
}
});
}
EDIT: Changed my code to what I currently have
I am generating a jsTree with this data, and to create the json data for that tree I am doing the above but putting the information variable into an object and iterating over it to create nodes. The issue isn't with the tree, so I won't include that here. I can even take that logic out to test.
So what is happening,
Is there a way to wait for it to be done?
EDIT: Providing more information
// IN A FILE CALLED loadinfo.js
// Returns system information promise
function getSystemInformation(){
return $.ajax({
type:"GET",
url: getUrl(), // url is defined somewhere else
cache: false,
dataType: "json"
});
}
// IN A FILE CALLED tree.js
// I have other variables from loadinfo.js that are here so they can communicate fine
$.when(getSystemInformation(), $.Deferred(function(deferred) {
$(deferred.resolve);
})).done(function(data) {
mapCache["system"] = data;
console.log("defer DONE!!");
$.each(mapCache["system"], function(index, system) {
var children = doDisplayChildNodes(system.name);
...
...
});
What I'm doing in this $.each is just grabbing data from mapCache["system"] and creating a "jstree" node. I do a child function to do the same thing, because I have child nodes associated with each system. All of this logic worked because it work working fine when I had the ajax call as "async:false" -- so I won't post that.
I receive the Cannot read property 'length' of undefined during the $.each. Which is strange because I have a "Watch" set on mapCache and after everything is loaded, mapCache is filled with the correct values. I am using Google Chrome debugging.
Upvotes: 2
Views: 8046
Reputation: 207501
You are not doing it right, callbacks do not return any data. There is no wait statement in JavaScript. The asynchronous call is executed and than the JavaScript keeps on processing the rest of the code.
Your code should be
function PUT_updateSystem(id) {
var system= {};
function processData(data) {
var information = data.info;
alert("Do next step");
}
system = getSystemInformation(name, processData);
}
Break your logic into two steps.
Upvotes: -2
Reputation: 95022
You used a callback, however you still used it with synchronous logic rather than asynchronous. Try doing it this way:
function PUT_updateSystem(id) {
var system = getSystemInformation(name);
system.done(function(data){
var information = data.info;
// do stuff with `information` here, not elsewhere.
});
}
// Returns system information promise
function getSystemInformation(name){
return $.ajax({
type:"GET",
url: getUrl(),
cache: false,
dataType: "json"
});
}
Upvotes: 6
Reputation: 39260
Asynchronyous means that the callback is called when PUT_updateSystem is already done.
The request is made to the server when you call getSystemInformation but right after it's called the function continues to var information = system.info; Before the server has time to respond so system.info; is not set yet. If you have a browser with developer tools IE, firefox with firebug plugin, Chrome all you need to do is press F12. And run the following code you might understand what callback means looking at the messages in the console (alert doesn't work because it pauses JavaScript execution.
function PUT_updateSystem(id) {
var system= {};
system= getSystemInformation(name, function(data){
var system = data;
// you re declare system here so it' actually not set
// if you want to set system in PUT_updateSystem you should
// do system = data; without the val
console.log("this comes last");
console.log("data is returned now",data);
return system;});
console.log("This comes first");
var information = system.info;
}
// Returns system information
function getSystemInformation(name,callback){
$.ajax({
type:"GET",
url: getUrl(),
cache: false,
dataType: "json",
success: function(data){
console.log("this comes second");
callback(data);
}
});
}
Upvotes: 0
Reputation: 786
function PUT_updateSystem(id) {
var system= {};
system= getSystemInformation(name, callbackfunction);
var information = system.info;
}
//callbackfuncion
function callbackfunction(data){
var system = data;
return system;
}
// Returns system information
function getSystemInformation(name,callback){
$.ajax({
type:"GET",
url: getUrl(),
cache: false,
dataType: "json",
success: function(data){
window[callback](data);
}
});
}
just instead of callback(data);
put window[callback](data);
and put the function name as a variable
Upvotes: 0