Angular 2 Ionic 2

Intro to ECMAScript 6 and Angular 2 for Ionic 1.x Developers



·

AngularJS 2 will be coming along soon, which involves basically a complete rewrite of the previous iteration of the popular framework. AngularJS is the backbone of Ionic, so big changes to Angular mean big changes to Ionic (which we will see in Ionic 2). Keep in mind that this doesn’t mean you’re going to have to recode all of your Ionic projects when Angular 2 comes out, as I mentioned in this blog post Angular 1.x and Ionic 1.x will be sticking around and will continue to be supported for as long as there are a significant amount of people using them.

The core philosophy of the AngularJS 2 redesign is summed up pretty well by the following quote:

We’re designing AngularJS 2 for the way the world will look when we believe folks will use it. In particular, this means targeting modern browsers and using ECMAScript 6.angularjs.blogspot.com

AngularJS 2 is being written for ECMAScript 6, which isn’t actually supported by browsers yet. In the mean time, Angular JS 2 will use the Traceur compiler which can compile ES6 code into ES5 code (and soon it will be using TypeScript instead of the Traceur compiler). This might seem a bit redundant (why write ES6 code when it’s going to be compiled into ES5 anyway?) but it will allow us to make use of all the fancy new ES6 features now and will really future proof the framework.

All this talk of ES5, ES6, TypeScript and blah blah blah, brings me to the point of this post: what the heck is ECMAScript 6?.

The purpose and roles of each of these things is something that confused me for a good while. It still does confuse me to a certain extent so please don’t expect insightful commentary from this post, but if you’re a little bit confused by all of this and a little bit scared about what it’s going to be like to code apps with Ionic 2 then you might find this post worth reading.

I’m going to attempt to cover what each of these things are and how they relate to Angular 2 and Ionic 2.

What is ECMAScript?

Before we talk about ECMAScript 6, we should probably talk about what ECMAScript even is. There’s quite a bit of history involved, but for the most part: ECMAScript is a standard, JavaScript is an implementation of that standard. ECMAScript defines the standard and browsers implement it. In a similar way, HTML specifications (most recently HTML5) are defined by the organising body and are implemented by the browser vendors. Different browsers implement specifications in different ways, and there’s varying amounts of support for different features.

What is ECMAScript 6?

The HTML5 specification was a bit of a game changer, and in a similar way so is the ECMAScript 6 specification. It will bring about some pretty drastic changes to the way you will code with JavaScript and in general will make JavaScript a much more mature language that is capable of more easily creating large and complex applications (which JavaScript was never really originally inteded to do).

Let’s look at some of the major additions in ES6 and some examples from es6-features.org.

Classes

We can already implement object oriented code in JavaScript by using functions and prototypes, but now ES6 will provide support for class definitions and all the associated goodies like inheritance by default.

With ES6 we could define a class like this:

class Shape {
    constructor (id, x, y) {
        this.id = id
        this.move(x, y)
    }
    move (x, y) {
        this.x = x
        this.y = y
    }
}

rather than the way we would do it currently:

var Shape = function (id, x, y) {
    this.id = id;
    this.move(x, y);
};
Shape.prototype.move = function (x, y) {
    this.x = x;
    this.y = y;
};

Modules

Modules allow you too modularise your code into packages that can be imported anywhere you need in your application, this is something that is going to be heavily used in Ionic.

For example in ES6 we could do the following:

//  lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593

//  someApp.js
import * as math from "lib/math"
console.log("2π = " + math.sum(math.pi, math.pi))

//  otherApp.js
import { sum, pi } from "lib/math"
console.log("2π = " + sum(pi, pi))

which would now be used in place of doing something like this:

//  lib/math.js
LibMath = {};
LibMath.sum = function (x, y) { return x + y };
LibMath.pi = 3.141593;

//  someApp.js
var math = LibMath;
console.log("2π = " + math.sum(math.pi, math.pi));

//  otherApp.js
var sum = LibMath.sum, pi = LibMath.pi;
console.log("2π = " + sum(pi, pi));

Promises

If you’ve used ngCordova then you will probably already be familiar with promises (a lot of JavaScript libraries implement promises) and why they are easier to use than callbacks. Promises provide a much nicer format for grabbing asynchronous data (e.g. data you need to wait for when you fetch something from a server or device), the current format of callbacks leads to ugly nested code that can become a nightmare to maintain.

ES6 adds native support for promises, which look like this:

function msgAfterTimeout (msg, who, timeout) {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout)
    })
}
msgAfterTimeout("", "Foo", 100).then((msg) =>
    msgAfterTimeout(msg, "Bar", 200)
).then((msg) => {
    console.log(`done after 300ms:${msg}`)
})

rather than callbacks which can end up looking like this:

function msgAfterTimeout (msg, who, timeout, onDone) {
    setTimeout(function () {
        onDone(msg + " Hello " + who + "!");
    }, timeout);
}
msgAfterTimeout("", "Foo", 100, function (msg) {
    msgAfterTimeout(msg, "Bar", 200, function (msg) {
        console.log("done after 300ms:" + msg);
    });
});

Block Scoping

Currently, if I define a variable in JavaScript it is available anywhere within the function that I defined it in. The new block scoping features in ES6 allow you to use the new let keyword to define a variable only within a single block of code like this:

for (let i = 0; i < a.length; i++) {
    let x = a[i]
    //etc.
}

The new const keyword can also be used for single assignments, so if you were to try and override that value it would throw an error.

There’s still a bunch of new stuff in ES6 that I haven’t mentioned yet like arrow functions, iterators, generators and much more, so for a more complete summary you should take a look at this summary by Luke Hoban.

TypeScript

Another concept we should cover off on is “TypeScript” which will be used for Angular 2. TypeScript’s own website defines it as:

…a typed superset of JavaScript that compiles to plain JavaScript.

If you’re anything like me then you still wouldn’t know what TypeScript is from that description (it seems easy to understand definitions are a big no-no in the tech world). In fact a StackOverflow post does a much better job at explaining what TypeScript is – basically, TypeScript adds typing, classes and interfaces to JavaScript.

Using TypeScript allows you to program in the way you would for stricter, object oriented languages like Java or C#. JavaScript wasn’t originally intended to be used for designing complex applications so the language wasn’t designed that way. It certainly is possible already to use JavaScript in an object oriented manner by using functions as classes as we discussed before but it’s not quite as clean as it could be.

In the StackOverflow thread I linked above the user also provided a good example of the differences between TypeScript and regular JavaScript. In TypeScript you might define a class like this:

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}  

but in regular JavaScript it would look like this:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

But wait… I mentioned before that ES6 is already adding the ability to create classes so why do we still need TypeScript? One redditor put it quite simply:

It’s called TypeScript not ClassScript 😉Cacodaimon

TypeScript still provides the ability to use static typing in JavaScript (which means it is evaluated at compile time, opposed to dynamic typing which is evaluated at run time). Using typing in TypeScript will look a little like this:

    function add(x : number, y : number) : number {
        return x + y;
    }
    add('a', 'b'); // compiler error

So in the example above the code won’t compile because we’re trying to supply characters to a function that expects only numbers.

The other obvious point here is that the JavaScript you write in TypeScript will be compiled, which is handy for ES6 because we need a way to compile it into valid ES5 code anyway (as I mentioned before, ES6 won’t work in browsers yet).

ECMAScript 6, Angular 2, and Ionic 2

Ok, so back to the original point of this post. How will all of this affect Ionic developers? Well, apps you build with Ionic 2 are going to look very different since we’ll be using ES6 and TypeScript.

To get more of an idea about how this might actually look, take a look at this blog post series by Max Lynch. He walks through how an app might be created with Angular 2, which will look a little something like this:

import {Component, View, bootstrap} from 'angular2/angular2';

// Annotation section
@Component({
  selector: 'my-app'
})
@View({
  inline: '<h1>Hello {{ name }}</h1>'
})
// Component controller
class MyAppComponent {
  constructor() {
    this.name = 'Alice'
  }
}
bootstrap(MyAppComponent)

Say hello to your new app.js file. You can see above that the code is making use of the new modules and components in ES6 (e.g. the import and @Component) and it’s also making use of the new class definitions as well. Max does a better job explaining the changes than I could so if you want more information please do take a look at his post.

This all might seem like a lot to take in and learn, so what are we getting out of it? Well for one, since Angular 2 is being designed specifically for mobile we can expect some general performance improvements right off the bat:

AngularJS 2 is a framework for mobile apps. It is for desktop as well, but mobile is the hard bit that we will get right first.angularjs.blogspot.com

Ionic 2 is going to get some updates of it’s own as well though (as in, more than just being made compatible with Angular 2). There’s not going to be any huge additions in Ionic 2 but Max Lynch has stated a few goals for Ionic 2, which in general are:

  • Similar features done better and faster
  • Have a simple set of core components
  • Make is super simple to build and use add ons for more components (like Tinder Cards)
  • Based on Angular 2
  • Potential to make it framework agnostic (i.e not tied specifically to Angular)

It’s still going to be the Ionic we all know and love, it’s just going to look a little different and that might take some getting used to. In the mean time you can continue using Ionic 1.x and I’m sure the Ionic team will release a bunch of stuff to help you migrate over to Ionic 2.

Conclusion

If you’re already used to building apps with Ionic 1 this will be a transition for sure, I think it is going to be well worth it though. Having experience with Ionic 1.x and Angular 1.x will also make it easier to understand and learn 2.x so hopefully that transition period won’t be too long. It really seems as though both Ionic and Angular are setting themselves up to be the powerhouses of the future, and it’s refreshing to see companies that are so forward thinking. I want to see HTML5 mobile applications taken as seriously as native applications are, and I think this is exactly the kind of move that will lead to that.

Resources

I’ve done quite a bit of research into all of this lately, so here’s a list of a few of the most useful articles and posts I came across:

What to watch next...