Appcelerator Titanium: Patterns and Best Practices

By Boydlee Pollentine , Trevor Ward
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies

About this book

Titanium Mobile has quickly become the platform of choice for many mobile developers and is growing and changing at a rapid rate. From the implementation of CommonJS,  MVC design patterns and more, the last year in Titanium development has been a rollercoaster of change for the better. With this knowledge at your disposal you’ll be creating top quality, highly capable and stable apps in no time.

This book shows you exactly how to implement all the latest Titanium Mobile best practices into your apps, from a thorough explanation of CommonJS with plenty of examples, through to structuring a complete MVC style codebase. With advanced topics such as implementing patterns and utilizing ACS, through to a thorough investigation of CommonJS and prototype, this book will take you from Titanium Novice to Titanium Ninja in no time!

"Appcelerator Titanium: Patterns and Best Practices" starts off with some explanations on JavaScript practices and advanced topics, before getting stuck into the new CommonJS pattern and using that to implement MVC-style architectures for your application. It continues in a practical, hands on manner, explaining how to perform cross device layouts with different techniques, and how to implement SQL alternatives such as JSONDB.

The book discusses some of the major advanced JavaScript topics, such as prototype and micro optimizations, before leading the developer into a thorough explanation of the CommonJS pattern, MVC implementation and advanced topics such as SQL alternatives and implementing designs for cross device layouts.

Publication date:
February 2013
Publisher
Packt
Pages
110
ISBN
9781849693486

 

Chapter 1. Understanding JavaScript Patterns

Since the initial introduction of JavaScript over 16 years ago it has grown from an "amateur" language often criticized for its shortcomings, into one of the most popular and useful programming languages available today. Apart from its widespread usage on the web, there are now numerous frameworks and libraries that not only use JavaScript, but place it first and foremost as the language of choice. The reasoning behind this is quite simple:

  • It's free, with a variety of interpreters and engines available (including Google's V8 engine).

  • It's one of the easiest programming languages to learn and being loosely-typed, it's quite forgiving.

  • It's everywhere. The skills you learn from JavaScript can be easily transferred from the Web to the desktop and all the way through to the mobile, using platforms such as Appcelerator's Titanium.

  • As JavaScript becomes even more popular with the rise of DOM-less engines such as NodeJS and Titanium, there is a huge and ever-growing number of third-party libraries available for JavaScript to tackle everything from OAuth to charting to date manipulation.

This is not to say that JavaScript today doesn't have its fair share of pitfalls and idiosyncrasies—far from it. To know and understand Titanium, you must first know and properly understand your JavaScript. The two are symbiotic, and the better you get at JavaScript, the better you understand its prototype-based structure, and the better Titanium Mobile developer you will become.

In this chapter, we'll avoid the basics and jump straight into some of the meatier aspects of JavaScript, as well as providing a few best practices and methods of optimizations along the way.

 

It's all object(ive)


JavaScript is completely classless. If you're approaching JavaScript and Titanium from another language (such as C# or Java), this fundamental change in thinking can take some getting used to. It does not mean, however, that JavaScript is not object-oriented, far from it. In fact, apart from standard primitives such as numbers, Booleans, and strings, almost everything in JavaScript is an object.

Whenever you declare a variable of a function in JavaScript, you effectively create an object. Functions, for example, automatically have the prototype object added to them as a variable whenever they are initialized, meaning all functions are already objects that contain at least one other object. If that sounds complicated then rest assured, it's really not. Objects are nothing more than a collection of named properties (key-value pairs), it's just that the values of these properties can be anything from a variable or a primitive to another function or object. These objects can be modified at any point during your application's lifecycle, including having members removed, changed, or added.

Note that even though there is not really a "method" as such in JavaScript, functions that are properties of other objects are often called methods in order to distinguish them from their parents.

Finally, it pays to note that there are two kinds of objects:

  • Native (or built-in) objects, such as Array, Data, or Math

  • User-defined objects, which are those that you create yourself

 

Understanding scope and the global object


Once you understand how scope and the global object works in JavaScript, you begin to understand why many developers struggled in the early days with memory leaks and poor performance in their Titanium applications, and why Appcelerator is encouraging all developers to make the move to a CommonJS code structure.

Note

CommonJS is a specification for defining how JavaScript acts outside of the browser. Its intention is that a developer could write JavaScript code for one system, and be able to run that same code on another system (or host environment) safe in the knowledge that it will be compliant and will work on both. We will be explaining CommonJS in depth in the next chapter.

First, let's define exactly what is meant by "global" and "local" scope. In JavaScript, everything is defined in function scope. This means that the variables declared within a function are only available from within that function and not outside of it. Conversely, it also means that variables defined outside of the scope of a function or statement declaration are therefore also available from within the said function or statement. The following example illustrates the difference between local and global variables:

var globalVariable = 'Titanium';

function bestMobilePlatform() {
  var localVariable = 'Phonegap';
      globalVariable += '!';
      return globalVariable;
}

alert( bestMobilePlatform() ); //alerts "Titanium!";
alert( bestMobilePlatform() ); //alerts "Titanium!!";
alert( localVariable ); //localVariable is not defined

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

The same principle in JavaScript applies to nested functions, which is called scope chain. This means that functions defined inside other functions will have access to their own variables, and the variables of their "parent" functions.

var a = 'Appcelerator'; //global variable

function bestMobilePlatform() {
  var b = 'Titanium';
  alert(bestMobileDevice()); //alerts "Apple iPhone" 
  alert(c); //undefined, won't execute (uncomment to test)
  function bestMobileDevice() {
    var c = 'Apple iPhone';
    alert(a + '  ' + b); //alerts "Appcelerator Titanium";
    return(c);
  }
}
bestMobilePlatform(); //call our nested function

The global object

So we now have a good understanding of scope in JavaScript, as well as the difference between local and global scope. By the same token, you should now understand what the global object is. It's the top-level object that holds all global objects and includes functions and variables that are declared in global scope. In the browser, the global object is known as window. In Titanium, the global object is defined as this inside your app.js file. So why do we want to avoid globals in our code?

  • Namespace pollution: This means that because global names are available everywhere, you may end up with a situation where you are using a global object when you think you're using a local one, or where you end up declaring a global object unintentionally (for example, because of a typo).

  • Non-locality: Good code is easy-to-read code, and the best code is created when it is modularized—meaning lots of small, localized functions or objects that are limited in their scope, making up the app as a whole. Over reliance on globals means that you will end up with a large mess where one part of your app can be hard to distinguish from another, otherwise known as "spaghetti code". It also means that every time your code needs to find a variable, it has to search the entire global scope which can slow your application down.

  • Collisions: If you declare global variables in your app.js file, and then include some external code using Ti.include() that use the same variable names, this can cause collisions in your code. It is one of the main reasons why Appcelerator (and this book) advocates the usage of CommonJS, which will be discussed in depth later in the book.

 

Code structure and formatting


JavaScript can be pretty forgiving, and if you're not careful, you can get into some pretty sloppy habits as a JavaScript developer. We've all seen code before that omits the semicolons, neglects the curly brackets, and in general is just poorly formatted. Often this is just an irritation as it makes code harder to read and understand, but sometimes it can lead to unwanted and unusual behavior.

Use semicolons and curly brackets

Let's first take a look at an example. While the following code is badly formatted, it will execute just fine and run without error:

//this is badly formatted code, but it will execute just fine
if (iLoveJavaScript === true)
  var message = 'Huzzah!"

What happens if this function is extended in order to make another function call? What if our comparison happens to be true?

//this is badly formatted code, and now it's broken code
var iLoveJavaScript = true;

if (iLoveJavaScript === true)
  var message = 'Huzzah!'  
      anotherFunctionCall();

You may initially think that the previous code would set our message variable to Huzzah! and then execute the function called anotherFunctionCall, but you'd be wrong. What actually happens is this:

//this is what actually executes 
var iLoveJavaScript = true;

if (iLoveJavaScript === true) {
  var message = 'Huzzah!';
}

anotherFunctionCall();

This means that regardless of whether the variable iLoveJavaScript is true or not, anotherFunctionCall() is always going to be executed. It is therefore best practice to always use curly braces, and always end lines of code with a semicolon, even if technically they aren't needed.

eval is evil

This should go without saying, but avoid the use of eval() at all costs. In case you weren't aware, the eval method takes a string containing JavaScript code and executes it at runtime. It's slow and full of potential security risks. While there are rare cases where you may want to use eval (for example, for complex user-generated mathematics, or inside a tool that runs code on the fly for testing purposes), there are almost always better methods available to you than the eval method.

Note

The alternatives to not using eval can be complex. One suggestion to avoid eval could include using a function instead. This keeps the evaluated code out of the global scope, i.e. new Function(data)();.

The curly bracket position

Implementing brackets is obviously important for good JavaScript code, but just as important is the location of your opening curly bracket. Developers' preferences on the position of the opening bracket tend to come from whatever language they are most used to. For example, in C# (.NET) code you would format your opening statements to have the curly bracket on the following line—in fact the IDE automatically formats it like this for you:

if(bangTidy === true)
{
   //do something within our if-statement
}

Others tend to place the first bracket on the same line as the if statement, which is the preferred way of formatting in JavaScript, as there are certain times when the JavaScript interpreter can make your code behave in unwanted ways. Take the following code for example:

//you would expect this if-statement to return an object with a name
//and an age property
if(bangTidy === true) {
     return
     {
         "name": "Keith Lemon",
         "age": 27
     }
}
//in reality, because of the position of the opening bracket, what is // really happening is this:
if(bangTidy === true) {
  return undefined;
      //this code is never reached
     {
         "name": "Keith Lemon",
         "age": 27
     }
}

So it's best practice to always have your opening curly bracket on the same line as your opening statement, to avoid potential parser errors.

Not all operators are created equal

JavaScript implicitly typecasts variables when they are compared. Let's take a look at a couple of non-explicit comparisons and review the results:

false == 0     (returns true)

0 == ''        (returns true)

true = 1       (returns true)

To avoid confusion (and for general readability) it is better to use the strict form comparison operators. This means instead of writing ==or!= you would instead use === or !==. These operators check both the type and value of the two variables you are comparing, as opposed to the standard operators which compare based on value alone.

false === 0    (returns false)

0 === ''       (returns false)
  
true !== 1     (returns true)

While not mandatory, comparing variables based on both type and value is a good practice to get into, as it makes your code look more consistent and can help you avoid errors in logic.

Formatting, commenting, and naming conventions

While not strictly enforced, the following name conventions are considered by many top JavaScript developers to be in keeping with best practices.They help to ensure that your code is readable and maintainable by any other developer who happens to come by and use it.

Object type

Best practice

Example

Constructors

As constructors are just functions, the best way to differentiate them is by capitalizing the first letter.

var ford = new Car();

Constants

Typically, constants in JavaScript are fully capitalized in order to set them apart from regular variables. Titanium's own API follows this naming pattern.

var PI = 3.1415926535897;
varFACEBOOK_API_KEY
          = '29239101199';

Function and method names

Public functions in JavaScript are generally defined in CamelCase. Titanium's own API follows this naming pattern.

Private functions are often defined using an underscore as the leading character in the name. This doesn't make them automatically private, but it does infer to the reader that they should be treated as such.

function goWest() {};
Ti.UI.createImageView() ;

var ford = {
    _getModel: function() {
       return 'Escort';
    };
};

Variable declarations

If you're declaring multiple variables at once, consider doing so in one statement, as it can make your code more concise and easier to read.

var width, height, depth;

Comments

It goes without saying (or it should)—comment your code! For most, this means block comments at the top of a file or function, and in-line comments where necessary throughout.

/*
 I am a block comment
*/
//I'm an in-line comment
 

Prototype


Understanding how Prototype works is an important part of understanding JavaScript, and an important part of understanding how Titanium Mobile works with CommonJS. Every object in JavaScript has a built-in property called prototype. The prototype property is created whenever a function is defined. The initial value of prototype is always an empty object. You can alter this empty object with your own properties, functions, and methods.

Let's say you are to create a new object called Car. This object has a number of properties that you wish to set using the constructor. We may want to create a new instance of Car called hatchback, and pass into the constructor a number of variables that describe the car in detail such as model, engineSize, and color. First, let's create our new constructor function called Car:

function Car(model, engineSize, engineType, color) {
  this.model = model;
  this.engineSize = engineSize;
  this.engineType = engineType;
  this.color = color;

  this.engine = function(){
    return this.engineSize + ' ' + this.engineType;
  };
};

Adding properties and functions to the prototype allows us to extend the functionality of this constructor's functions. Here's how we can do that using prototype:

Car.prototype.yearOfManufacture = 2012;
Car.prototype.manufacturer = 'Ford';
Car.prototype.getInfo = function(){
  return {
    engine: this.engine,
    modelDetails: this.model + ' ' + this.yearOfManufacture,
    manufacturer: this.manufacturer,
    colorOption: this.color,
    price: '$15,000'
  };
};

Note

This only applies to your own objects, not those built-in Titanium proxy ones such as Ti.UI.View.

Using the methods and properties added to the prototype is then easy, as shown here where we are creating a new object called hatchback. You'll note from the output that all the functions and variables that we predefined in the prototype are now already available as part of the hatchback object.

var hatchback = new Car('Focus', '1.4', 'Petrol', 'Blue');
alert(hatchback.yearOfManufacture); //alerts 2012
alert(hatchback.manufacturer); //alerts Ford
Ti.API.info(hatchback.getInfo()); //echoes the getInfo object

So why is this so beneficial in Titanium? Imagine you had a view, and it was called MyView. This MyView object held a couple of labels, an imageview, and a tableview—all of which need to be defined before you go off to your database or web service and fetch data to assign to their value/data properties. Using prototype, we can define all these things when we're creating a new object using the constructor of MyView. This means greater code reuse, and greater isolation between different parts of your code, making it overall more maintainable.

We will be using prototype a lot during the chapter on CommonJS and providing specific examples of how to utilize it efficiently in Titanium.

 

Micro optimizations


While the following practices may not bring you vast speed improvements (and not doing them will certainly not make your code "bad" in any way), they are nonetheless good habits to get into.

Declaring variables outside the for statements

When you're executing a lengthy for statement, there is no need to make the JavaScript engine work harder than it has to. Take the following example, which calculates the length of the array myArray every time the loop reruns:

//avoid constant recalculation of the length of myArray
for(var c = 0; c < myArray.length; c++){
   //do something with myArray[c]
}

A much better way of writing this for statement is to cache the length of the array in a variable. This way, the value of myArray.length is retrieved only once, and used during the entire loop.

//a better way of looping through myArray
var max;
for(var c = 0; max = myArray.length,c < max; c++){
   //do something with myArray[c]
}

If the order that you access the array values in is not important, then it's also slightly quicker to count down than up. This is because it's more efficient to count down to zero than it is to calculate and equate your values to an arbitrary number, such as the length of myArray. For example:

//looping backwards is faster
var c;
for(c = myArray.length; c--;){
   //do something with myArray[c]
}

//alternatively, you can use a while loop in this instance
while(c--) {
  //do something with myArray[c]
}

Using forEach instead of for loop

Where possible, it's best to use a forEach loop in lieu of a standard forloop, particularly if you're looping through array values. For example, we could alter our previous sample code to look something like this:

function printResults(element, index, array){
  //do something with myArray[index];
  Ti.API.info(index + ' = ' + element);
}

myArray.forEach(printResults);

Using shortcuts for simple if statements

Sometimes, you simply need to check a single value and determine whether it matches a specific value before proceeding in your code. This might be as simple as determining whether an object is null, or checking that an operator is true or false. In many cases, it's simpler to use a few shortcuts.

//here we are checking if this object is null
var myObject;
if(myObject !== null) {
  myObject = {
    name: 'Boydlee'
  };
}

//a better way of declaring this object would be 
var myObject = myObject || {
    name: 'Boydlee'
};


//in this example we're checking if a value equals true, and 
//assigning a variable accordingly
var dinner = '';

if(isBritish === true) {
  dinner = 'Burger & Chips';
}
else {
  dinner = 'Hamburger & Fries';
}


//a simpler way to perform this check would be to use the
//pattern "variable = (condition) ? True-value : false-value;
dinner = isBritish ? 'Burger & Chips' : 'Hamburger & Fries';
 

Summary


Having a good working knowledge of JavaScript fundamentals is going to ensure that you write better, faster, and more stable Titanium applications, while sticking to the general principles of good code structure and formatting will keep your code neat, concise, and as error-free as possible. There are many books available online that deal specifically with JavaScript patterns and best practices to a much greater depth than we have gone into here, and it is well worthwhile to have at least one of these on hand at all times.

Here are some suggested books you might find useful:

In the next chapter, we are going to be looking at best practices as they relate to the Titanium Mobile API itself, before diving into writing Titanium applications using CommonJS.

About the Authors

  • Boydlee Pollentine

    Boydlee Pollentine is a keen mobile developer who has created numerous apps for the iTunes and Android store and a number of indie games. He is passionate about mobile development and in particular the Appcelerator Titanium platform, and is both a Titanium-certified application developer and a member of the Titans evangelist group. He is also the organizer of Europe's first Titanium mobile development conference, tiConf EU (http://ticonf.eu). Boydlee has been a software engineer and programmer for the last 10 years, primarily focused on web technologies and Microsoft's .NET platform, and during that time has worked for numerous small and large organizations, those of particular note including a number of Australian federal government departments, state departments, banks, and media organizations. He currently lives in Norfolk and works as a freelance Titanium developer via his own digital agency, Tipsy & Tumbler Limited (http://www.tipsyandtumbler.co.uk), and runs a small blog dedicated to mobile development at http://boydlee.com.

    Browse publications by this author
  • Trevor Ward

    Trevor Ward has been developing business applications for over 20 years. Starting as a Cobol Developer, he has worked on various large scale projects that included the Y2K issues. Moving into web development in the late 90s using Perl, HTML, JavaScript, and Oracle, he was a part of the team that developed internal business applications for Jaguar cars.

    After moving on, he was able to update his skills for Ruby on Rails and Adobe Flex, before 18 months ago picking up on the mobile development platform. He uses Titanium exclusively for mobile development and is an Appcelerator Titan (community expert), TCAD and TCE qualified, and spends as much time as possible, answering questions on the forums.

    Browse publications by this author
Book Title
Unlock this book and the full library for FREE
Start free trial