Preparing for Ionic 2 and Angular 2

Artboard 1

Ionic and angularjs will receive big updates in the near future, meaning Ionic 2 and angular2 are released. This will be the next big step in mobile app development. We are all really excited about that, but if you are developing professional software for clients as we do, you often cannot switch to frameworks in beta phase.

Currently we are trying, as many others out there, to get a smooth transition to the new technology. Therefore we will be ready when there is a release of Ionic 2. Question is, how to prepare? We thought about this for a while and concluded the best way to start is the new language Ionic 2 is using. For those who didn’t follow the scene: angular2 and Ionic 2 is recommended to be written in ES6 (ES2015) or Typescript. Both development Teams favor Typescript, so do we.

This is why most of this post will be about how to integrate Typescript into our current generator-m-ionic stack and how to take advantages from the new ‘language’.

 

Integrating Typescript

First of all, for those who haven’t heard of ES6: it’s basically the next level of JavaScript. Typescript is a superset of ES6, it adds more features, of which the biggest one is types. Yes types in JavaScript. To find out more about the basics, take a look at typescript.org.

So what do we have to do, to write Typescript in our apps? There will be a few steps required, but don’t worry, there is a step by step guide here. In the linked repository you will also find the examples of this blog post as a simple todo application.

Since most browsers don’t understand all of ES6 or Typescript, we have to transpile the code from Typescript to JavaScript. The transpile step will be done by the scripts we included in the previous steps and should just ‘work’. If you are fearing unreadable code after transpilation, we have something for you: sourcemaps. Thanks to sourcemaps it will be possible to debug the sourcecode (Typescript) in the browser. The browser will e.g. map your log and debugger statements to the corresponding Typescript files and lines, while running the transpiled JavaScript code. Means most of the time you will not touch or look at the transpiled JavaScript files.

 

Get your hands dirty – writing Typescript

Done with the talking, let’s continue with writing some Typescript. First of all we will create a controller. Just add a new file todo-ctrl.ts to your main module in the folder controllers and put in the following code. For comparison we put in most examples Typescript and JavaScript side by side, so you can compare the code better.

/// <reference path="../../../typings/browser.d.ts" />

class TodoCtrl {
  constructor(
    private $scope: ng.IScope
  ) {
    this.$scope.$on(
      '$ionicView.afterEnter', () => this.hello('World')
    );
  }

  public hello (name) {
    console.log(`Hello ${name}!`)
  }
}

angular.module('main')
  .controller('TodoCtrl', TodoCtrl);
angular.module('main')
  .controller('TodoCtrl', function ($scope) {
    var self = this;

    $scope.$on('$ionicView.afterEnter', function () {
      self.hello('World');
    });

    this.hello = function (name) {
      console.log('Hello ' + name + '!');
    }
  });

When a watcher (gulp watch) is running, it will be transpiled and can be interpreted by your browser. The angular app will work, even the dependency injection. Because it’s based on named parameters. With generator-m-ionic it’s even minification save, thanks to ng-annotate. We also used three ES6 features here classes, arrow function and template literals, which are quite handy compared to the ‘old’ ES5 equivalent.

It looks exactly the same for a service, just register one like this on your module.

angular.module('main')
  .service('TodoService', TodoService)

 

Using angular components

The next step is to use components instead of directives. They work similar, but components are much more like angular2-components and less complicated than directives. You can get more information on components in this blogpost.

A simple example could look like this:

class TodoComponent {
  private todo: TodoModule.ITodo;
};

angular.module('main')
.component('todoItem', {
  bindings: {
    item: '='
  },
  controller: TodoComponent,
  controllerAs: 'todoC',
  template: `
    <ion-item>
      {{todoC.item.description}}
    </ion-item>
  `
});
angular.module('main')
.component('todoItem', {
  bindings: {
    item: '='
  },
  controller: function () {},
  controllerAs: 'todoC',
  template: `
    <ion-item>
      {{todoC.item.description}}
    </ion-item>
  `
});

As you can see, you can write the most parts easily in Typescript. From my perspective this is great.

 

Nice Typescript features

Furthermore I would like to talk about the possibilities you get with Typescript and how you can write better and more readable AngularJS code with it. One of the handiest features is Typescript definitions. For most common libraries and frameworks, there is a registry called typings, which provides those definition files. Therefore you can use code completion in your editor or IDE. But how does it work? It’s fairly simple, you just have to add the references path to the d.ts file and an annotation to any variable like this:

/// <reference path="../../../typings/browser.d.ts" />
...
var $ionicLoading: ionic.loading.IonicLoadingService;

The next time you use the $ionicLoading variable the editor will show you the possible functions or properties of it. This means: no ugly switching between documentation and code, when you simply forgot the functions name. I think this is huge for ionic developers, because you have to have so many different apis in mind like ionic, angular, cordova, DOM, browser apis, etc.

Another great feature of Typescript are Interfaces. Many of the apps we write are heavy business apps. In this apps for example you have to enter data in tons of input fields. Thus you got big models and sometimes you forget which properties are allowed, required and which types they use. With Typescript you can use Interfaces and the Editor can tell you all this.

module TodoModule {
  'use strict';
  export interface ITodo {
    id: string;
    description: string;
    createDate: number;
    done: boolean;
    note?: string;
  }
  class TodoService {
    public todos: Array<ITodo> = [];

    addTodo (description: string) {
      this.todos.push({
        id: Date.now().toString(),
        description: description,
        createDate: Date.now(),
        done: false
      });
    }
  }
}
'use strict';
angular.module('main')
  .service('TodoService', function () {
    var self = this;
    this.todos = [];

    this.addTodo = function (description) {
      self.todos.push({
        id: Date.now().toString(),
        description: description,
        createDate: Date.now(),
        done: false
      })
    }
  });

In the example code you can see, that we reference the Interface on an array generic, so when we are pushing data to this array, the Typescript compiler can tell us wether we used all required properties in the correct type or not. There are many possibilities to use Interfaces, but in all cases you will get more readable and maintainable code with not that big of an effort.

 

What else?

There are many more examples for writing Typescript in ionic1 out there. I also have to give credit to the guys at Ionic, they had a nice blog series on that topic. For the german folks, the guys from angularjs.de had also a very good post on this.

You can even do more to let your apps look like angular2 code e.g. using ng-forward. Or use the new module system introduced by ES6. This is covered by a blog post from the awesome guys at thoughtram.

Conclusively, I am quite happy with the described way. You can write modern Typescript code, but it still looks similar to Ionic in JavaScript. It’s a step in the right direction and can be adopted easily. I think in the beginning it will be a bit unfamiliar, but you don’t have to use every concept right away. Instead you can progressively enhance your code.

 

Leave a Reply

Your email address will not be published. Required fields are marked *