Preparing for Angular 2

It’s official – Angular 2.0.0 was just released. If you have been putting off learning Angular 2 until it was finalized, that’s OK, but now is the time to get ready and to dive into it. In this post I will give you five steps that you can take to prepare for Angular 2:

  1. Use TypeScript
  2. Use @types Declaration Files
  3. Use Modules
  4. Use controllerAs
  5. Use Angular 1.5

If you are new to Angular and want to learn more about it then check out Webucator’s Angular 1 and Angular 2 training courses.

Use TypeScript

JavaScript (JS) might be what we call it but its real name is ECMAScript, which is based on a standard that is developed by a committee and then later adopted by browser vendors like Google, Microsoft, and Mozilla. This entire process takes a long time. In fact, ECMAScript 5 (ES5)  is the “current” implementation supported broadly by browsers, and it was finalized in 2011. This  process has improved significantly with evergreen browsers that are updated frequently. In fact, browser vendors are quickly implementing the next release of ECMAScript: ES6 or ES2015 (the latter is now preferred). This new release contains lots of changes to the language that we know and love. And, with the accelerated rate of releases by browser vendors, the ECMAScript standards committee intends to do annual releases. In fact, ES2016 was finalized in June 2016 and they are already working on the next release.

What does all of that have to do with TypeScript? Because TypeScript enables developers to use ES2015 and ES2016 features today. This is because TypeScript is a superset of JavaScript (or ECMAScript) and is transpiled into JavaScript.

How can I use ES2015 and ES2016 features today if they are not yet completely implemented by browsers? Because TypeScript can compile your ES2015 code down to ES5. And, we can use polyfills to fill in the gap in the browser.

TypeScript also adds strong typing to our code. As we all know, JavaScript is a dynamically typed language. So why would we want to impose strong typing? Because we can take advantage of the TypeScript compiler to catch issues in our code before testing in the browser.

Last, but not least, Angular 2 is written in TypeScript and relies on types for decorating your classes; for example, the @Component() decorator. You’ll learn more about that when you dive into Angular 2. But knowing that Angular 2 requires using TypeScript means that we should start learning and using TypeScript today.

Here is an example of some Angular 1 code written using vanilla JavaScript:

angular.
  module('heroList').
  component('heroList', {
    templateUrl: 'hero-list/hero-list.template.html',
    controller: function HeroListController() {
      this.heroes = [
        {
          name: 'Mr. Nice',
          id: 11
        }, {
          name: 'Narco',
          id: 12
        }, {
          name: 'Bombasto',
          id: 13
        }
      ];
    }
  });

Here is an example of how we might use TypeScript for the same controller:

interface IHero {
  name: string;
  id: number;
}

export class HeroController {

  public heros: IHero[];

  constructor() {
    this.heroes = [
      {
        name: 'Mr. Nice',
        id: 11
      }, {
        name: 'Narco',
        id: 12
      }, {
        name: 'Bombasto',
        id: 13
      }
    ];
  }
}

With TypeScript we can take advantage of classes, which are part of the ES2015 standard. We can also use interfaces and strong typing. These are just some of the advantages of using TypeScript today even if you are not using Angular 2 yet.

Use @types Declaration Files

Like many languages, TypeScript supports the use of declaration (or header) files. This enables us as developers to take advantage of strong typing when using libraries like Angular and jQuery. TypeScript 2 has a new way of loading declaration files using the Node Package Manager (npm). For example, let’s install the declaration files for both Angular and jQuery:

$ npm install @types/angular --save-dev
$ npm install @types/jquery --save-dev

Now, let’s take a look at a directive that we created here at Webucator for displaying an accordion interface:

import { WebucatorAccordionController } from "./accordion.controller";

/**
 * The webucator-accordion directive.
 *
 * @class AccordionDirective
 */
export class AccordionDirective implements ng.IDirective {

  public controller: any = "WebucatorAccordionController";
  public controllerAs: string = "webucatorAccordionController";
  public restrict: string = "A";
  public scope: boolean = true;

  /**
  * The link function is responsible for registering DOM listeners as well as updating the DOM.
  *
  * @class AccordionDirective
  * @method link
  * @param $scope {ng.IScope} The scope for this directive
  * @param $element {ng.IAugmentedJQuery} The JQuery instance members object.
  * @param $attributes {ng.IAttributes} An object containing normalized DOM element attributes.
  * @param webucatorAccordionController {WebucatorAccordionController} A new instance of the controller.
  */
  public link: ng.IDirectiveLinkFn = (
    scope: ng.IScope, 
    element: ng.IAugmentedJQuery, 
    attributes: ng.IAttributes,
    webucatorAccordionController: WebucatorAccordionController
  ) => {
    console.log("[AccordionDirective:link] Creating webucator-accordion directive instance.");
  };

  /**
  * Create the directive.
  *
  * @class AccordionDirective
  * @method Factory
  * @static
  * @@return {ng.IDirectiveFactory} A function to create the directive.
  */
  public static Factory(): ng.IDirectiveFactory {
    return () => new AccordionDirective();
  }
}

Some things to note about my directive:

  • First, I’m using TypeScript, so I’m going to take advantage of strong typing.
  • The AccordionDirective class implements the ng.IDirective interface. This interface is part of the TypeScript declaration file for Angular that we installed previously.
  • Next, I define a public variable named controller that is of type string and that is set to the value “WebucatorAccordionController”. This should look familiar if you are used to using the angular.directive() method in vanilla JS. Instead of returning an object in our angular.directive() function, we have defined a class that represents the directive; and it has the same publicly available variables as the configuration object has.
  • I then specify the instance name of my controller using the controllerAs property.
  • Then I restrict the directive to only an attribute directive.
  • Then I specify the scope as private by setting the value of my scope property to true. Again, note the type of the variable is boolean.
  • Next, note that I specify the types for each argument to the link() function. This helps provide intellisense when using Visual Studio Code or WebStorm.
  • Finally, I create a static method named Factory() that returns an IDirectiveFactory function for creating a new AccordionDirective.

Use Modules

One thing I did not note about the TypeScript code above for my AccordionDirective class is that I am referencing my controller class that is named WebucatorAccordionController. This class is not in the same file (or module) as my AccordionDirective class. So how does TypeScript know what it is? Take a look again, and at the top of the code, I use the import statement to import the class WebucatorAccordionController out of the module “accordion.controller”. A module is just a file. And our module can have multiple named exports. In the case of my directive, I am using the export statement before defining the class. This statement indicates that the class can be exported out of the module. Then, I can use the import statement in another module to import the named export; in this case, my AccordionDirective class.

In the example of creating an accordion directive and component, you might have two modules:

  1. accordion.directive.ts
  2. accordion.controller.ts

This allows us to easily break up our Angular directives and controllers into modules. Using TypeScript and ES2015, we can do this today with our Angular 1 code.

Use controllerAs

This has been said many times: use controllerAs. This is also recommended in John Papa’s style guide for Angular 1. There are several benefits to this, including avoiding $scope. And for some Angular developers that will come as a huge relief.

To understand this, let’s take a look at the WebucatorAccordionController class:

export class WebucatorAccordionController {

  private _q: string;

  public get q(): string {
   return this._q;
  }

  public set q(q: string) {
    //store query
    this._q = q;

    //perform search
    this.search();
  }

  public search(): WebucatorAccordionController {
    //log
    console.log(`[WebucatorAccordionController:search] searching: {q: ${this._q}}.`);

    //code omitted

    return this;
  }
}

Some things to note about the code above:

  • I have a private variable named _q that is a string.
  • I am using the new ES2015 style getter (or accessor) and setter (or mutator) methods.
  • When setting the value of the q property we will invoke the search() method.
  • Our search method does a bunch of work, which I have omitted here. If you want to learn more about this, check out my other blog post on creating a Searchable Bootstrap According using Angular.

Let’s take a look at the input element that uses ngModel to bind to the q property in the controller:

<input type="search" placeholder="find courseware" ng-model="webucatorAccordionController.q" ng-model-options="{debounce: {'default': 500, 'blur': 0}}">

My search input is bound to the q property, and when set, will invoke the search() method. I also have defined some custom ngModelOptions to debounce the input so that the search() method is only invoked when the user either stops updating the value for 500 milliseconds or the focus on the element is lost (blurred).

As you can see, we didn’t have to use $scope at all. Using the controllerAs syntax enables us to directly bind to publicly available properties and methods in our controller. When you start working with Angular 2 you will find that the same is true, but even better, you will not need to scope your controller. You simply access or invoke the publicly available properties and methods defined in your component’s class.

Use Angular 1.5

My final recommendation in preparing for Angular 2 is to start using Angular 1.5. Angular 1.5 introduces the component, which is similar to Angular 2’s component architecture. This will make the mental transition smoother from directives and controllers in Angular 1 to the more simplified syntax of components in Angular 2.

Finally, once you’re ready to start using Angular 2, look at the UpgradeAdapter. This enables you to bootstrap a hybrid Angular 1 + Angular 2 application, providing an upgrade bridge of our application without having to do a forklift upgrade.

About Webucator

Webucator provides instructor-led training to students throughout the US and Canada. We have trained over 90,000 students from over 16,000 organizations on technologies such as Microsoft ASP.NET, Microsoft Office, Azure, Windows, Java, Adobe, Python, SQL, JavaScript, Angular and much more. Check out our complete course catalog.