I'm trying to make a simple function with js & jquery but I can't get this to work.
From what I understand, when I declare a variable without var it becomes global but I can pass a variable from a jquery callback to my main function.
function fetchEvents(start,end){
ret = [];
$j.getJSON("index.php?page=agenda_google_ajax&action=list&start="+start+"&end="+end,function(data){
console.log(data); // works ok
ret = data;
});
console.log(ret); // equals [] :'(
return ret;
}
-
you might want to read up on javascript asyncKJYe.Name– KJYe.Name2011年03月29日 14:40:44 +00:00Commented Mar 29, 2011 at 14:40
-
Does ret variable needs to be an array?yojimbo87– yojimbo872011年03月29日 14:41:38 +00:00Commented Mar 29, 2011 at 14:41
7 Answers 7
From what I understand, when I declare a variable with var it becomes global..
The opposite is true. When you omit var, the variable becomes global. Always use var!
From the Google JavaScript Style Guide:
When you fail to specify var, the variable gets placed in the global context, potentially clobbering existing values. Also, if there's no declaration, it's hard to tell in what scope a variable lives (e.g., it could be in the Document or Window just as easily as in the local scope). So always declare with var.
As for your problem with console.log(ret); // equals [] :'(...
$j.getJSON() is not a synchronous method call. The method runs asynchronously, so your code effectively says:
ret = [];
console.log(ret);
If you need to use the data returned from your getJSON() after it is executed, you can call a method within your callback function:
$j.getJSON("index.php?page=agenda_google_ajax&action=list&start="+start+"&end="+end,
function(data){ // this is your callback function
console.log(data); // works ok
doSomething(data); // process the returned JSON
}
});
2 Comments
Your problem is that $.getJSON uses a callback so when your fetchEvents function is called it returns before the callback is executed.
what you want to do is in the callback populate/do the stuff you want to do.
as you have pointed out console.log works ok in the callback
Comments
It seems like you are confusing 2 issues here.
The first is that var does not make a variable gloabl. The opposite is true. That is omitting var will make a variable global.
The second is the getJSON callback method does not execute synchronously. It will execute once the http request is completed. So there is no expectation that ret will be set to the value immediately after making the getJSON call.
Comments
try adding var to var ret = [];
adding var to it does not make it global, omitting it makes it global it is added to the global window object.
Comments
That's because ret is evaluated BEFORE you get a response from ajax. Try
function fetchEvents(start,end){
$j.getJSON("index.php?page=agenda_google_ajax&action=list&start="+start+"&end="+end,function(data){
console.log(data); // works ok
var ret = data
whatsRet (ret);
});
}
function whatsRet (ret) {
console.log(ret); // equals data :)
}
Comments
The problem you have is about writing asynchronous code.
When you call getJSON, the inner function will not be called until getJSON returns something. This means that code is no longer executed top-down, your program continues the execution even when getJSON is still getting the data.
You should provide a callback instead of a return:
var fetchEvents = function (start, end, callback) {
$j.getJSON("index.php?start="+start+"&end="+end, function (data) {
callback(data);
});
};
// Now you can use fetchEvents which will be asynchronous too
fetchEvents(0, 10, function (data) {
console.log(data);
})
You can simpify fetchEvents event more by passing the callback directly to getJSON.
var fetchEvents = function (start, end, callback) {
$j.getJSON("index.php?start="+start+"&end="+end, callback);
};
PD: I simplified the query for readability.