
Question:
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;
}
Answer1:<blockquote>
From what I understand, when I declare a variable with var it becomes global..
</blockquote>The opposite is true. When you omit var
, the variable becomes global. Always use var!
From the <a href="http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml" rel="nofollow">Google JavaScript Style Guide</a>:
<blockquote>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.
</blockquote>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
}
});
Answer2: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
Answer3: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.
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.
Answer6: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 :)
}
Answer7: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.