53690

Javascript variable scope

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.

Answer4:

try adding var to var ret = [];

Answer5:

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.

Recommend

  • Do publishAs values have to be unique in Angular Dart?
  • How can I see the output of my program in the Turbo C IDE?
  • Naming Generated Functions in Propel
  • Missing windows authentication IIS component because of Windows Vista Home Premium edition… any fixe
  • Generic collection in generic class
  • How to fail Phing without triggering backtrace
  • Linq Full Outer Join on Two Objects
  • How to get the index of element in the List in c#
  • How to override jQuery promise callback
  • Graceful pod termination
  • Regex for nested values
  • iOS Cordova first plugin - plugin.xml to inject a feature
  • VBA Excel, loop through variables
  • converter json to two dimensional array
  • Elasticsearch script query involving root and nested values
  • Why use database factory in asp.net mvc?
  • Low TTL with Leveled Compaction, should I reduce gc_grace_seconds to improve read performance withou
  • How do I configure context broker accept post requests from my remote sensor?
  • x64 applications using gdi+: what are the consequences on performance?
  • Time complexity of a program which involves multiple variables
  • Admob requires api-13 or later can I not deploy on old API-8 phones?
  • How do I alternate colors in Flat List (React Native)
  • Listbox within Listbox and scrolling trouble in Windows Phone 7 Silverlight
  • If I include Java 8 in my Android app does that affect which devices it will work on?
  • HTML download movie download link
  • How to recover from a Spring Social ExpiredAuthorizationException
  • Updating server-side rendering client-side
  • Javascript Callbacks with Object constructor
  • ILMerge & Keep Assembly Name
  • Large data - storage and query
  • jquery mobile loadPage not working
  • WOWZA + RTMP + HTML5 Playback?
  • Confusion with PayPal's monthly billing cycle
  • Unanticipated behavior
  • How to set the response of a form post action to a iframe source?
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?