Managing Alloy.js global objects

Titanium is great. Alloy is great. The ability to build cross-platform apps with an MVC approach is GREAT but with great power comes great responsibility (and a few gotchas). One such thing to look out for is using Alloy.js especially when it comes to global variables.

In “classic” Titanium, it was as simple as creating a variable without prefixing it with the var keyword. This was always bad and can cause all kinds of unexpected behaviour.

A CommonJS approach helps to prevent pollution of the global scope and this is essentially how Alloy works. However there’s one file in an Alloy project, Alloy.js, which can be used for any global variables and functions using the notation:

Alloy.Globals.myKey = “12345”

or

Alloy.Globals.myFunc = function(args) {

}

These declarations make these two objects available throughout the Alloy application and that’s good (although there’s a whole other debate to have with developers on what should be in Alloy.js and if it should be used at all. That’s another post).

There’s one issue here. The way that Alloy.js is integrated into your application at build time means that essentially ANY variable you put in Alloy.js will be available globally.

That means if you do:-

var myKey = “12345”

myKey can now be accessed throughout your app.

There’s a simple fix to avoid this, and that’s the block scope the Alloy.js code to ensure it’s completely isolated.

You can do this as follows:-

(function(){

   var myVar = “foo”;

   Alloy.Globals.myKey = “12345”;

   Alloy.Globals.myFunc = function(args) {

   }

})();

With this structure, anything within the top level function is isolated and local to the function. That means the myVar variable is local, and won’t leak out globally. The Alloy.Globals calls work as they did previously, creating Globally accessible objects within the Alloy.Globals namespace.

With this pattern you have control over what is global, and what isn’t.

Freelance Web/App/Mobile Developer as BouncingFish • Speaker • TCAD + TCD Certified Developer/Instructor • Titanium Titan.


Comments

  • Jonathan Wheat

    Thanks Jason.

    Being new to Alloy (1 app in the stores), these tips are good to know. I guess its just pure luck I didn’t make that mistake, or maybe deep down inside I knew the proper way. Nah, lets face it, it was luck.

    -Jon

  • Patrick Seda

    Awesome tip. This should probably be used as a standard template for every project.

  • Nelson

    I’m new to Alloy+Ti nad is not clear for me if in alloy, you can pollute the global scope by defining a var in any controller, for example, could do I do this:

    index.js:
    var someIndexData = {};
    someIndexData.someIndexFunction = function(){
    // Do something
    }

    controller1.js:
    alert(someIndexData);
    someIndexData.someIndexFunction();

  • Fokke Zandbergen

    No, only vars defined in `alloy.js` (which will be merged into Titanium’s `app.js` will be globally available.

  • Flavio De Stefano

    I personally never understood why you shoudn’t declare global vars in alloy.js

    I mean, why can’t I declare :

    “`
    var App = {};
    App.x = 2;
    App.func = function(){};
    “`

    instead of `Alloy.Globals` ?

  • Fokke Zandbergen

    Nothing wrong with that.. it’s just yet another global var.

  • Manuel Conde

    I suppose it’s only a convention, but I see some advantages, like a clear way to find global vars in your code, and a way to avoid to overwrite a global var by error.

    For example, with your data, you make a new controller and do a var App = [];
    Maybe in the future you want to use the global var in some part of your code and you don’t remember your local definition with the same name…

  • Steven House

    I think the reason to not declare globally using non Alloy.Globals syntax is that you can’t guarantee backwards compatibility if they choose to change how alloy.js exposes variables in scope. So… to future proof I’d say.