WTH is Injection Token in Angular


Angular is a very advanced and thought-out framework where Angular Components, Directives, Services, and Routes are just the tip of the iceberg. So my intention with WTH-series of posts is to understand something that I do not know yet in Angular (and its brethren) and teach others as well.

Let us start with a simple example, an Angular Injectable Service that we all know and use extensively in any Angular project. This particular example is also very common in Angular projects where we often maintain environment-specific configurations.

// environment.service.ts
import { Injectable } from '@angular/core';

@Injectable({providedIn: 'root'})
export class Environment1 {
    production: boolean = false;
}

Here, we annotated a standard ES6 class with @Injectable decorator and forced Angular to provide it in the application root, making it a singleton service i.e. a single instance will be shared across the application. Then, we can use a Typescript constructor shorthand syntax to inject the above service in Component’s constructor as follows.

// app.component.ts
import { Component } from '@angular/core';

import { Environment1 } from './environment.service'; 

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html'
})
export class AppComponent  {
    constructor(private environment1: Environment1) {}
}

But, often such environment-specific configurations are in the form of POJOs and not the ES6 class.

// environment.service.ts
export interface Environment {
    production: boolean;
}
export const Environment2: Environment = {
    production: false
};

So the Typescript constructor shorthand syntax will not be useful in this case. However, we can naively just store the POJO in a class property and use it in the template.

// app.component.ts
import { Component } from '@angular/core';

import { Environment, Environment2 } from './environment.service'; 

@Component({
    selector: 'my-app'
    templateUrl: './app.component.html'
})
export class AppComponent  {
    environment2: Environment = Environment2;
}

This will work, no doubt!? But, this defeats the whole purpose of Dependency Injection (DI) in Angular which helps us to mock the dependencies seamlessly while testing.

InjectionToken

That’s why Angular provides a mechanism to create an injection token for POJOs to make them injectable.

Creating InjectionToken

Creating an Injection Token is pretty straight-forward. First, describe your injection token and then set the scope with providedIn (just like the Injectable service that we saw earlier) followed by a factory function that will be evaluated upon injecting the generated token in the component.

Here, we are creating an injection token ENVIRONMENT for the Environment2 POJO.

// injection.tokens.ts
import { InjectionToken } from '@angular/core';

import { Environment, Environment2 } from './environment.service'; 

export const ENVIRONMENT = new InjectionToken<Environment>(
  'environment',
  {
    providedIn: 'root',
    factory: () => Environment2
  }
);

Feel free to remove providedIn in case you do not want a singleton instance of the token.

Injecting InjectionToken

Now that we have the Injection Token available, all we need is inject it in our component. For that, we can use @Inject() decorator which simply injects the token from the currently active injectors.

// app.component.ts
import { Component, Inject } from '@angular/core';

import { Environment } from './environment.service'; 
import { ENVIRONMENT } from './injection.tokens';

@Component({
  selector: 'my-app'
  templateUrl: './app.component.html'
})
export class AppComponent  {
  constructor(@Inject(ENVIRONMENT) private environment2: Environment) {}
}

Additionally, you can also provide the Injection Token in @NgModule and get rid of the providedIn and the factory function while creating a new InjectionToken, if that suits you.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { Environment2 } from './environment.service'; 
import { ENVIRONMENT } from './injection.tokens';

@NgModule({
    imports:      [ BrowserModule ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ],
    providers: [{
        provide: ENVIRONMENT,
        useValue: Environment2
    }]
})
export class AppModule { }

Demo

https://stackblitz.com/edit/angular-2fqggh

That’s it for all. Keep Rocking \m/ \0/

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.
Advertisement

Enable tree-shaking in Rails/Webpacker: A Sequel


A month ago, I wrote a blog post explaining a hacky way to enable tree-shaking in Rails/Webpacker project at Simpl. I would definitely recommend skimming through the previous post if you have not already.

In this post, we will directly jump into a more robust and stable solution. But before that, I want to resurrect my old memories for you that haunted me for months wherein a broken manifest.json was generated during webpack compilation at a random place. This time, after upgrading @rails/webpacker and related webpack plugins, the problem has been escalated beyond repair wherein an incomplete but valid manifest.json was generated randomly having fewer pack entries than expected. So even the generated manifest.json has little chance of succor by the hacky NodeJS fix_manifest.js script I had written to fix the broken JSON last time.

After a bit of googling my way out, I learned that webpack, with multi-compiler configurations, compiles each webpack configuration asynchronously and disorderly. Which is why I was getting an invalid manifest.json earlier.

Imagine two webpack compilations running simultaneously and writing to the same manifest.json at the same time:

{
  "b.js": "/packs/b-b8a5b1d3c0c842052d48.js",
  "b.js.map": "/packs/b-b8a5b1d3c0c842052d48.js.map"
}  "a.js": "/packs/a-a3ea1bc1eb2b3544520a.js",
  "a.js.map": "/packs/a-a3ea1bc1eb2b3544520a.js.map"
}

Using different manifest file for each pack

Yes, this is the robust and stable solution I came up with. First, you have to override Manifest fileName in every webpack configuration in order to generate a separate Manifest file for each pack such as manifest-0.json, manifest-1.json, and so on. Then, use the same NodeJS script fix_manifest.js with a slight modification to concatenate all the generated files into a final manifest.json which will be accurate (having all the desired entries) and valid (JSON).

For that, we have to modify the existing generateMultiWebpackConfig method (in ./config/webpack/environment.js) in order to remove the existing clutter of disabling/enabling writeToEmit flag in Manifest which we no longer need. Instead, we will create a deep copy of the original webpack configuration and override the Manifest plugin opts for each entry. The deep copying is mandatory so that a unique Manifest fileName can endure for each pack file.

const { environment } = require('@rails/webpacker')
const cloneDeep = require('lodash.clonedeep')

environment.generateMultiWebpackConfig = function(env) {
  let webpackConfig = env.toWebpackConfig()
  // extract entries to map later in order to generate separate 
  // webpack configuration for each entry.
  // P.S. extremely important step for tree-shaking
  let entries = Object.keys(webpackConfig.entry)

  // Finally, map over extracted entries to generate a deep copy of
  // Webpack configuration for each entry to override Manifest fileName
  return entries.map((entryName, i) => {
    let deepClonedConfig = cloneDeep(webpackConfig)
    deepClonedConfig.plugins.forEach((plugin, j) => {
      // A check for Manifest Plugin
      if (plugin.opts && plugin.opts.fileName) {
        deepClonedConfig.plugins[j].opts.fileName = `manifest-${i}.json`
      }
    })
    return Object.assign(
      {},
      deepClonedConfig,
      { entry: { [entryName] : webpackConfig.entry[entryName] } }
    )
  })
}

Finally, we will update the ./config/webpack/fix_manifest.js NodeJS script to concatenate all the generated Manifest files into a single manifest.json file.

const fs = require('fs')

let manifestJSON = {}
fs.readdirSync('./public/packs/')
  .filter((fileName) => fileName.indexOf('manifest-') === 0)
  .forEach(fileName => {
    manifestJSON = Object.assign(
      manifestJSON,
      JSON.parse(fs.readFileSync(`./public/packs/${fileName}`, 'utf8'))
    )
})

fs.writeFileSync('./public/packs/manifest.json', JSON.stringify(manifestJSON))

Wrap up

Please note that the compilation of a huge number of JS/TS entries takes a lot of time and CPU, hence it is recommended to use this approach only in a Production environment. Additionally, set max_old_space_size to handle the out-of-memory issue for production compilation as per your need – using 8000MB i.e. 8GB in here.

$ node --max_old_space_size=8000 node_modules/.bin/webpack --config config/webpack/production.js
$ node config/webpack/fix_manifest.js

Always run those commands one after the other to generate fit and fine manifest.json ๐Ÿ˜™

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

RTFC


I really could not think of a better title for this post because it is not just about using an @Input property setter instead of the life-cycle hook ngAfterViewInit. Hence the title is pretty much inspired from RTFM where “Manual” is replaced by “Code”.

Itโ€™s about how important it is to read the code.

Just read the code..!

Last month I had published the Angular blog post on NgConf Medium in which I had proposed various ways to use jQuery plugins in Angular. If you have not read it yet, do read it here and comment if any. Unfortunately, I did not get lucky enough to be ngChampions (Kudos to those who become) and hence I have decided to publish the sequel here on my personal blog.

So after publishing the first post, I went on reading the source code for Material Badge component, just casually.

And to my surprise, I noticed 3 profound things:

Structural Directive over Component

It depends on the functionality you want to build into the component. If all you want to do is alter a single DOM then always go for a custom structural directive instead of writing a custom component. Because the custom component mostly introduces its own APIs unnecessarily.

For example, take a look at the app-toolbar-legends component from the last article. Remember, Iโ€™m not contradicting myself in this article, however, for this particular jQuery plugin in Angular, we could safely create an Angular Directive rather than having the Angular Component with its own API in terms of class and icon attributes below.

<app-toolbar-legends class="btn-toolbar-success" icon="fa-bitcoin" [toolbarConfig]="{position: 'right'}">
  <div class="toolbar-icons hidden">
    <a href="#"><i class="fa fa-bitcoin"></i></a>
    <a href="#"><i class="fa fa-eur"></i></a>
    <a href="#"><i class="fa fa-cny"></i></a>
  </div>
</app-toolbar-legends>
<app-toolbar-legends class="btn-toolbar-dark" icon="fa-apple" [toolbarConfig]="{position: 'right', style: 'primary', animation: 'flip'}">
  <div class="toolbar-icons hidden">
    <a href="#"><i class="fa fa-android"></i></a>
    <a href="#"><i class="fa fa-apple"></i></a>
    <a href="#"><i class="fa fa-twitter"></i></a>
  </div>
</app-toolbar-legends>

That means we can simplify the usage of the jQuery plugin in Angular by slapping the Angular Directive on the existing markup as follows. There is no need for an extraneous understanding of where class or icon values go in the component template, itโ€™s pretty clear and concise in here. Easy, just slap a directive appToolbarLegends along with the jQuery plugin configurations.

<div class="btn-toolbar btn-toolbar-success" [appToolbarLegends]="{position: 'right'}" >
  <i class="fa fa-bitcoin"></i>
</div>
<div class="toolbar-icons hidden">
  <a href="#"><i class="fa fa-bitcoin"></i></a>
  <a href="#"><i class="fa fa-eur"></i></a>
  <a href="#"><i class="fa fa-cny"></i></a>
</div>


<div class="btn-toolbar btn-toolbar-dark" [appToolbarLegends]="{position: 'right', style: 'primary', animation: 'flip'}">
  <i class="fa fa-apple"></i>
</div>
<div class="toolbar-icons hidden">
  <a href="#"><i class="fa fa-android"></i></a>
  <a href="#"><i class="fa fa-apple"></i></a>
  <a href="#"><i class="fa fa-twitter"></i></a>
</div>

Generate Unique Id for the DOM

I wanted a unique id attribute for each instance of the toolbar in order to map them to their respective toolbar buttons. Iโ€™m still laughing at myself for going above and beyond just to generate a unique ID with 0 dependencies. Finally, StackOverflow came to the rescue ๐Ÿ˜…

Math.random().toString(36).substr(2, 9)

But while reading the source code for Material Badge component, I found an elegant approach that I wish to frame on the wall someday ๐Ÿ˜‚. This will generate a unique _contentId for each instance of the directive without much fuss.

import { Directive } from '@angular/core';
let nextId = 0;
@Directive({
  selector: '[appToolbarLegends]'
})
export class LegendsDirective {
  private _contentId: string = `toolbar_${nextId++}`;
}

@Input property setter vs ngAfterViewInit

Before we get into the getter/setter, letโ€™s understand when and why to use ngAfterViewInit. Itโ€™s fairly easy to understandโ€Šโ€”โ€Šit is a life cycle hook that triggers when the View of the component or the directive attached to is initialized after all of its bindings are evaluated. That means if you are not concerned with querying the DOM or DOM attributes which have interpolation bindings on them, you can simply use Class Setter method as a substitute.

import { Directive, Input } from '@angular/core';
let nextId = 0;
@Directive({
  selector: '[appToolbarLegends]'
})
export class LegendsDirective {
  private _contentId: string = `toolbar_${nextId++}`;
  @Input('appToolbarLegends')
  set config(toolbarConfig: object) {
    console.log(toolbarConfig); // logs {position: "right"} object
  }
}

The Class Setters are called way before ngAfterViewInit or ngOnInit and hence they speed up the directive instantiation, slightly. Also, unlike ngAfterViewInit or ngOnInit , the Class Setters are called every time the new value is about to be set, giving us the benefit of destroying/recreating the plugin with new configurations.

Demo Day

Thanks for coming this far. So the moral of the story is to do read code written by others, does not matter which open source project it is.

Just read the code..!

https://stackblitz.com/edit/angular-zgi4er?embed=1&file=src/app/app.component.ts
If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

TypeScript: Generocks


It’s been a while that this blog post about Typescript Generics was in my drafts (not sure why) and finally it is out. ๐ŸคžBut before we get into Generics, we should be aware of what makes Types in Typescript exciting.

Typescript allows us to type check the code so that errors can be caught during compile time, instead of run time. For example, the following code in Javascript may look correct at compile time but will throw an error in a browser or NodeJS environment.

const life = 42;
life = 24;  // OK at compile time

In this case, Typescript may infer the type of the variable life based on its value 42 and notify about the error in the editor/terminal. Additionally, you can specify the correct type explicitly if needed:

const life: number = 42;
life = 24; // Throws an error at compile time

Named Types

So there are few primitive types in Typescript such as number, string, object, array, boolean, any, and void (apart from undefined, null, never, and recently unknown). However, these are not enough, especially when we use them together in a large project and we might need a sort of an umbrella type or a custom type for them to hold together and be reusable. Such aliases are called named types which can be used to create custom types. They are classes, interfaces, enums, and type aliases.

For example, we can create a custom type, MyType comprising a few primitive types as follows.

interface MyType {
  foo: string;
  bar: number;
  baz: boolean;
}

But what if we want foo to be either string or object or array!? One way is to copy the existing interface to MyType2 (and so on).

interface MyType2 {
  foo: Array<string>;
  bar: number;
  baz: boolean;
}

The way we pass any random value to a function with the help of a function parameter to make the function reusable, what if we allowed to do the same for MyType as well. With this approach, the duplication of code will not be needed while handling the same set but different types of data.  But before we dive into it, let us first understand the problem with more clarity. And to understand it, we can write a cache function to cache some random string values.

function cache(key: string, value: string): string {
  (<any>window).cacheList = (<any>window).cacheList || {};
  (<any>window).cacheList[key] = value;
  return value;
}

Because of the strict type checking, we are forcing the parameter value to be of type String. But what if someone wants to use a numeric value? I’ll give you a hint: what operator in Javascript do we use for a fallback value if the expected value of a variable is Falsy? Correct! we use || a.k.a. logical OR operator. Now imagine for a second that you are the creator of Typescript Language (Sorry, Anders Hejlsberg) and willing to resolve this issue for all developers. So you might go for a similar solution to have a fallback type and after countless hours of brainstorming, end up using a bitwise operator i.e. | in this case (FYI, that thing is called union types in alternate dimensions where Anders Hejlsberg is still the creator of Typescript).

function cache(key: string, value: string | number): string | number {
  (<any>window).cacheList = (<any>window).cacheList || {};
  (<any>window).cacheList[key] = value;
  return value;
}

Is not that amazing? Wait, but what if someone wants to cache boolean values or arrays/objects of custom types!? Since the list is never ending, looks like our current solution is not scalable at all. Would not it be great to control these types from outside!? I mean, how about we allow to define placeholder types inside the above implementation and provide real types from the call site instead.

Generic Function

Let us use ValueType (or use any other placeholder or simply T to suit your needs) as a placeholder wherever needed.

function cache<ValueType>(key: string, value: ValueType): ValueType {
  (<any>window).cacheList = (<any>window).cacheList || {};
  (<any>window).cacheList[key] = value;
  return value;
}

We can even pass the custom type parameter MyType to the cache method in order to type check the value for correctness (try changing bar‘s value to be non-numeric and see for yourself).

cache<MyType>("bar", { foo: "foo", bar: 42, baz: true });

This mechanism of parameterizing types is called Generics. This, in fact, is a generic function.

Generic Classes

Similar to the generic function, we can also create generic classes using the same syntax. Here we have created a wrapper class CacheManager to hold the previously defined cache method and the global (<any>window).cacheList variable as a private property cacheList.

class CacheManager<ValueType> {
  private cacheList: { [key: string]: ValueType } = {};
  cache(key: string, value: ValueType): ValueType {
    this.cacheList[key] = value;
    return value;
  }
}
new CacheManager<MyType>().cache("bar", { foo: "bar", bar: 42, baz: true });

Even though the above code is perfect to encourage reusability of CacheManager while caching all types of values, but someday in future, there will be a need to provide varying types of data in MyType‘s properties as well. That exposed us to the original problem of MyType vs MyType2 (from the Named Types section above). To prevent us from duplicating the custom type MyType to accommodate varying types of properties, Typescript allows using generic types, even with interfaces, which makes them Generic Interfaces. In fact, we are not restricted to use only one parameter type below, use as many as needed. Additionally, we can have union types as a fallback to the provided parameter types. This permits us to pass an empty {} object while using the generic interface wherever we desire the default types of values.

interface MyType<FooType, BarType, BazType> {
  foo: FooType | string;
  bar: BarType | number;
  baz: BazType | boolean;
}
new CacheManager<MyType<{},{},{}>>().cache("bar", { foo: "bar", bar: 42, baz: true });
new CacheManager<MyType<number, string, Array<number>>>().cache("bar", { foo: 42, bar: "bar", baz: [0, 1] })

I know that it looks a bit odd to pass {} wherever the default parameter types are used. However, this has been resolved in Typescript 2.3 by allowing us to provide default type arguments so that passing {} in the parameter types will be optional.

Generic Constraints

When we implicitly or explicitly use a type for anything such as the key parameter of the cache method above, we are purposefully constraining the type of key to be of type String. But we are inadvertently allowing any sort of string here. What if we want to constraint the type of key to be the type of one of the interface properties of MyType only!? One naive way to do so is to use String Literal Types for key below and in return get [ts] Argument of type '"qux"' is not assignable to parameter of type '"foo" | "bar" | "baz"'error when the key type qux does not belong to MyType. This works correctly, however, because of the hard-coded string literal types, we can not replace MyType with YourType interface since it has different properties associated with it as follows.

interface YourType {
  qux: boolean;
}
class CacheManager<ValueType> {
  private cacheList: { [key: string]: ValueType } = {};
  cache(key: "foo" | "bar" | "baz", value: ValueType): ValueType {
    this.cacheList[key] = value;
    return value;
  }
}
new CacheManager<MyType<{},{},{}>>().cache("foo", { foo: "bar", bar: 42, baz: true }); // works
new CacheManager<MyType<{},{},{}>>().cache("qux", { foo: "bar", bar: 42, baz: true }); // !works
new CacheManager<YourType>().cache("qux", { qux: true }); // !works but should have worked

To make it work, we’ve to manually update the string literal types used for key each time in the class implementation. However, similar to Classes, Typescript also allows us to extend Generic Types. So that we can get away with the string literal types "foo" | "bar" | "baz" of key with the generic constraint i.e. KeyType extends keyof ValueType as follows. Here, we are forcing the type-checker to validate the type of key to be one of the interface properties provided in CacheManager. This way we can even serve previously mentioned YourType without any error.

class CacheManager<ValueType> {
  private cacheList: { [key: string]: ValueType } = {};
  cache<KeyType extends keyof ValueType>(key: KeyType, value: ValueType): ValueType {
    this.cacheList[key] = value;
    return value;
  }
}
new CacheManager<MyType<{},{},{}>>().cache("foo", { foo: "bar", bar: 42, baz: true }); // works
new CacheManager<MyType<{},{},{}>>().cache("qux", { foo: "bar", bar: 42, baz: true }); // !works
new CacheManager<YourType>().cache("qux", { qux: true }); // works

Alright, that brings us to the climax of Generics. I hope \0/ Generocks  \m/ for you.

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

Angular2: Dependency Injection


In the last article, we’ve explored basic differences between Angular 1 and 2 with respect to Component over Directive, TypeScript over ES5, ES6 Class over Controller, and Decorators/Annotations. We’ve pretty much got acquainted with setting up Angular2 in TypeScript with SystemJS to begin our journey with Angular2 in coming weeks. In this article, we’ll investigate how dependency injection that we always loved is different in Angular2 than Angular1. We are not going to cover what dependency injection is in this article though, so if you are not familiar with it yet, follow the documentation for more information.

Angular1

As usual, we’ll quickly go through the Angular1 example. Let’s take a simple example (HTML and JS) from my free ebook on Angular1 Directives that explores how DI works in Angular1. Notice we’ve used ngController directive in which we are going to inject a custom service. Also stare at ngApp directive which was a recommended way to bootstrap an application automatically in Angular1 rather than manually using angular.bootstrap method.

<br>
&lt;html ng-app="DI"&gt;<br>
&lt;head&gt;<br>
  &lt;title&gt;AngularJS: DI&lt;/title&gt;<br>
  &lt;script src="../bower_components/angular/angular.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../js/ch01/di.js"&gt;&lt;/script&gt;<br>
&lt;/head&gt;<br>
&lt;body ng-controller="SayHi"&gt;</p>
<p>&lt;h1&gt;Check the console&lt;/h1&gt;</p>
<p>&lt;/body&gt;<br>
&lt;/html&gt;<br>

Here is the JavaScript code for the above example. We have defined the custom service named Hello and later injected the same into the controller called SayHi.

<br>
var App = angular.module('DI', []);<br>
App.service('Hello', function() {<br>
  var self = this;<br>
  self.greet = function(who) {<br>
    self.name = 'Hello ' + who;<br>
  }<br>
});</p>
<p>App.controller('SayHi', function(Hello) {<br>
  Hello.greet('AngularJS');<br>
  console.log(Hello.name);<br>
});<br>

Now that we’ve our demo up and running, it’s time to migrate it to Angular2.

Angular2

Let us first update the JS code first and walk through the changes.

<br>
import { NgModule, Component, Injectable } from '@angular/core';<br>
import { BrowserModule } from '@angular/platform-browser';<br>
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';</p>
<p>@Injectable()<br>
class HelloService {<br>
  name: string;</p>
<p>  greet(who) {<br>
    this.name = 'Hello ' + who;<br>
  }<br>
}</p>
<p>@Component({<br>
  selector: 'ng-app',<br>
  template: '&lt;h1&gt;Check the console&lt;/h1&gt;'<br>
})<br>
export class DIComponent {<br>
  constructor(public Hello: HelloService) {<br>
    this.Hello.greet('Angular2');<br>
    console.log(this.Hello.name);<br>
  }<br>
}</p>
<p>@NgModule({<br>
  declarations: [DIComponent],<br>
  imports:      [BrowserModule],<br>
  providers:    [HelloService],<br>
  bootstrap:    [DIComponent]<br>
})<br>
export default class MyAppModule {}</p>
<p>platformBrowserDynamic().bootstrapModule(MyAppModule);<br>

We are already familiar with Component, ES6 Class, bootstrap, etc. jargons from the previous article as these are the backbone of Angular2. The only difference here is the service, HelloService. However, if you notice, the service is itself a ES6 Class similar to our application component, DI. Just like @Component annotation is there to tell Angular2 to treat a ES6 class as a component, the @Injectable annotation annotated the ES6 Class as an Angular2 Service that is injected elsewhere.

In the above example, we’ve injected the service via providers options in the @NgModule. This way the instance of the service will be available for the entire component only and its child components, if any. However, services in Angular2 are not singleton by nature unlike Angular1 which means if the same service is injected as a provider in a child component, a new instance of the service will be created. This is a confusing thing for beginners so watch out.

The public Hello: HelloService parameter in the constructor is equivalent to Hello: HelloService = new HelloService();. It means Hello is an instance of HelloService and of a type HelloService (optional). One benefit of annotations/decorators in Angular2 in my opinion is that there is no confusion over Factory vs Service vs Provider, instead it’s just a ES6 class.

Slight changes compared to the previous example is that we need to give more configurations in SystemJS for typescript compilers to emit decorator MetaData so that generated ES5 code will work fine in a browser.

<br>
{<br>
  "compilerOptions": {<br>
    "target": "ES5",<br>
    "module": "commonjs",<br>
    "moduleResolution": "node",<br>
    "sourceMap": true,<br>
    "emitDecoratorMetadata": true,<br>
    "experimentalDecorators": true,<br>
    "removeComments": false,<br>
    "noImplicitAny": false<br>
  }<br>
}<br>

Remember experimentalDecorators flag enables experimental support for ES7 decorators in TypeScript and emitDecoratorMetadata flag emits design-type metadata for decorated declaration in ES5 output, especially, for public Hello: HelloService code in the constructor as we’d seen before. Using the alternative mentioned above will not need these flags though.

Now let us update HTML markup.

<br>
&lt;html&gt;<br>
&lt;head&gt;<br>
  &lt;title&gt;Angular2: DI&lt;/title&gt;<br>
  &lt;meta charset="UTF-8"&gt;<br>
  &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;</p>
<p>  &lt;!-- 1. Load libraries --&gt;<br>
  &lt;script src="../node_modules/core-js/client/shim.min.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/zone.js/dist/zone.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/reflect-metadata/Reflect.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/systemjs/dist/system.src.js"&gt;&lt;/script&gt;</p>
<p>  &lt;!-- 2. Configure SystemJS --&gt;<br>
  &lt;script src="../systemjs.config.js"&gt;&lt;/script&gt;<br>
  &lt;script&gt;<br>
    System.import('ch01/di').catch(function(err){ console.error(err); });<br>
  &lt;/script&gt;<br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
  &lt;!-- 3. Display the application --&gt;<br>
  &lt;ng-app&gt;Loading...&lt;/ng-app&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;<br>

Wrap up

That’s it guys..! Wolksoftware‘s blog has covered a great intro to reflection in Typescript, if interested. In the next post, we’ll explore two-way databinding in Angular2, but meanwhile Checkout Dependency Injection in action.

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

Angular2: The First Time


Angular 2.0 is lot like Angular1 but still different in its own terms and you’ll see why as we go along. Purpose of this article is to migrate one of the simplest Angular1 examples to Angular2 and understand benefits as well as pain-points. For the record, Angular2 aimed to build web applications in three different languages or flavours i.e. JavaScript (ES5/ES6), Typescript(ES6+), and Dart. If you interested in other two then the 5-minute-session will give you a head-start to understand how it could be done. However, I’m going to use Typescript over JavaScript here because in my opinion it feels more natural. This article is for the ones who worked with Angular1 before.

Angular1

Let’s take a simple example (HTML and JS) from my free e-book on Angular1 Directives that explores how data binding works in Angular1. Let us quickly take a look at our good old Angular1 HTML template and then we’ll move to new shiny Angular2 version of it. But for now, notice we’ve used ngBind directive over double-curly notation for data-binding, obviously to avoid FOUC as we all know. Also checkout ngApp directive which was a recommended way to bootstrap an application automatically in Angular1 without using angular.bootstrap method.

<br>
&lt;html ng-app="App"&gt;<br>
&lt;head&gt;<br>
  &lt;title&gt;HTML/DOM Template in AngularJS&lt;/title&gt;<br>
  &lt;script type="text/javascript" src="../bower_components/angular/angular.js"&gt;&lt;/script&gt;<br>
  &lt;script type="text/javascript" src="../js/ch01/angular-template.js"&gt;&lt;/script&gt;<br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
  &lt;span&gt;Hello, &lt;span ng-bind="name"&gt;&lt;/span&gt;&lt;/span&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;<br>

Here is the JavaScript code for the above example which simply binds a value of name property on the $rootScope.

<br>
var App = angular.module('App', []);<br>
App.run(function($rootScope) {<br>
  $rootScope.name = 'AngularJS';<br>
});<br>

Now that we’ve our demo up and running, its time to migrate it to Angular2.

Angular2

Let us first update the JS code and walk-through the changes. Give it a very long, hard stare to get familiar with the following snippet, I’ll wait.

<br>
import { NgModule, Component } from '@angular/core';<br>
import { BrowserModule } from '@angular/platform-browser';<br>
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';</p>
<p>@Component({<br>
  selector: 'ng-app',<br>
  template: '&lt;span&gt;Hello, &lt;span [textContent]="name"&gt;&lt;/span&gt;&lt;/span&gt;'<br>
})<br>
class MyAppComponent {<br>
  name: string = 'Angular2';<br>
}</p>
<p>@NgModule({<br>
  declarations: [MyAppComponent],<br>
  imports:      [BrowserModule],<br>
  bootstrap:    [MyAppComponent]<br>
})<br>
export default class MyAppModule {}</p>
<p>platformBrowserDynamic().bootstrapModule(MyAppModule);<br>

Your first reaction would be, “Alright, that looks familiar..!”. Well it is except few things, let us go over one by one. But before that we must know that Angular2 moved from a concept of directives to components to leverage web-components specs so that developers can use Polymer components with Angular2 templates. Basic idea is to break down monolithic application into small pieces i.e. components and plug them together at the end under main component like we have here. Each component should have one or more Classes or Functions to store data (name in this case) and necessary methods (not defined in the example above). Please note we no longer use $scope in Angular2 as this is somewhat like CtrlAs syntax from Angular1. When Angular2 instantiates MyApp class, all properties or methods defined will be accessible via keyword this.

Update: As per RC5 release, angular2 introduced a concept of NgModule metadata which plays an important role in the compilation process, especially offline compilation. Because of NgModule, Angular2 will able to lazy load components on demand by resolving component dependencies efficiently. So every component should expose a NgModule for other components to import and reuse. Ideally, NgModule should be extracted into it’s own file importing various components, services, pipes, etc. but for the sake of readability, we’ll have it in the same file along with the component.

export statement

Angular2 has adopted modularity at its core unlike Angular1 wherein you could only define modules without any built-in support for lazy loading. Using ES6 export module syntax, you can export functions, objects, or primitives that other classes can use in Angular2. Having one export class per module recommended though. We’ve defined a property, name with a type string which is optional in TypeScript.

Import Statement

With the same export class syntax, Angular2 has organized its code base so that developers can import what they need in a module. In this example, we are only importing Component and NgModule annotations from angular2/core library and platformBrowserDynamic method from angular/platform-browser-dynamic modules. Note that the extension is optional in the definition.

Using platformBrowserDynamic().bootstrapModule method from angular2 browser module (similar to angular.bootstrap in Angular1), we can bootstrap the NgModule named MyAppModule. Angular2 is a lot different from Angular1 on the architectural level. Angular1 only targeted Desktop and Mobile web browsers, but Angular2 is platform agnostic, that means it can be used to write Native mobile apps using NativeScript or Cordova, run angular2 application inside web workers, and to enable server-side rendering with NodeJS or so. For now, we’ll just run it in a web browser by pulling down browser specific bootstrap method as above.

Annotation

The strange-looking syntax above the class called as a Class Decorator that annotates and modifies classes and properties at design time. Wolksoftware’s engineering blog has great articles on decorators and metadata in Typescript. In a nutshell, Angular2 uses decorators/annotations to make dependency injection possible. To simplify it, let us take a small requirement.

Imagine you want to log a function name and passed arguments to browser console every time a method invoked without modifying the function body. In the following example, @debug is a method decorator that attached a special behavior to the method body. overtime a method called, the decorator will find a method name being called and it’s parameter that we can log. Here is a working demo if interested.

<br>
export class AnnotationExample {<br>
  @debug<br>
  life(n: number) {<br>
    return n;<br>
  }<br>
}</p>
<p>function debug(target: Function, fnName: string, fn: any) {<br>
  return {<br>
    value: function (argument: number) {<br>
      document.getElementsByTagName('body')[0].textContent = `function "${fnName}" was called with argument "${argument}"`;<br>
    }<br>
  };<br>
}</p>
<p>var whatIs = new AnnotationExample();<br>
whatIs.life(42);<br>

On the same note, @component annotation/decorator tells Angular2 that the defined class, MyApp is an Angular2 Component not just a ES6 class. And once it’s defined as the component, Angular2 needs to know how the component supposed to be consumed in HTML or which template to render once it’s registered. That’s why we need to pass the meta data as above such as selector, template, etc.

Notice selector name need not be the same as the class name unlike Angular1. There is no restrict option anymore, instead use a tag name (ng-app) or a property name (with square brackets [ng-app]) or a class name (.ng-app) directly as a selector (I think a comment selector is dropped..!). Also note that we have used a double curly notation for data binding here as there is no ngBind directive available, but you can use property binding (which we’ll explore in future posts) to get the same feeling with <span>Hello, <span [textContent]="name"></span></span>.

Now let us update HTML markup.

<br>
&lt;html&gt;<br>
&lt;head&gt;<br>
  &lt;title&gt;HTML/DOM Template in Angular2&lt;/title&gt;<br>
  &lt;meta charset="UTF-8"&gt;<br>
  &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;</p>
<p>  &lt;!-- 1. Load libraries --&gt;<br>
  &lt;script src="../node_modules/core-js/client/shim.min.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/zone.js/dist/zone.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/reflect-metadata/Reflect.js"&gt;&lt;/script&gt;<br>
  &lt;script src="../node_modules/systemjs/dist/system.src.js"&gt;&lt;/script&gt;</p>
<p>  &lt;!-- 2. Configure SystemJS --&gt;<br>
  &lt;script src="../systemjs.config.js"&gt;&lt;/script&gt;<br>
  &lt;script&gt;<br>
    System.import('ch01/angular-template').catch(function(err){ console.error(err); });<br>
  &lt;/script&gt;<br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
  &lt;!-- 3. Display the application --&gt;<br>
  &lt;ng-app&gt;Loading...&lt;/ng-app&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;<br>

If you remember, we’d included just angular.js in Angular1 template before, however, Angular2 relies on couple of other JavaScript libraries that you need to inject along with it. But things may change eventually, as it’s just a RC release (at the time of writing this article, and who knows we have to just include one file as before).

Refer SystemJS Wiki for more details to suite your needs. And as you guessed already, we have created a custom element in the body at the end to kick it off.

Wrap up

Peek at a demo..!. That’s it guys..! This is the exact flow you’ll always be using to write new components in Angular2. I liked the progress with Angular2 and Typescript, I would recommend to use Visual Studio Code Editor over SublimeText to feel at home. Be hopeful that many of the things we explored would be simplified by the time it reaches 1.0 (stable), I mean 2.0 ๐Ÿ˜‰

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.