Twenty one reason to use Angular 2 and TypeScript

Our company SuranceBay developed a platform for the insurance industry, and most of the UI for this system was written using Apache Flex framework (formerly Adobe Flex). Flex is an excellent framework for developing Web UI, but it requires Flash Player, which is not in favor anymore. Our quest for a good JavaScript framework started about four years ago.

After trying several pilot JavaScript projects we noticed a substantial drop in our developers’ productivity. A task that required one day in Flex would need three days in any JavaScript framework, including AngularJS. The main reasons were lack of types in JavaScript, poor IDE support, and absence of compiler’s support.

When we learned that Google started development of the Angular 2 framework with TypeScript as a recommended language for development, we became early adopters. A year later we can confirm that the Angular 2/TypeScript duo is the most productive way of developing mid-to-large size Web applications that can run in any modern Web browser as well as on mobile platform.

These are the main reasons why I believe that Angular 2 and TypeScript are the right tools for developing Web applications:

1. The tooling support is as good as on Java or .Net platforms
2. TypeScipt code analyzer warns you about the errors as you type
3. Using TypeScript classes and interfaces makes the code more concise and easy to read and write
4. Clean separation between the code that renders UI and the code that implements application logic
5. The UI doesn’t have to be rendered in HTML, and there are already products supporting native UI rendering for iOS and Android
6. Angular 2 offers a simple mechanism for modularizing application with support of lazy loading of modules
7. The TypeScript compiler generates JavaScript that a human can read
8. The TypeScript code can be compiled into ES3, ES5, or ES6 versions of JavaScript
9. The router supports complex navigation scenarios in a single-page applications
10. Dependency injection give you a clean way to implement loose coupling between components and services
11. Binding and events allows you to create reusable and loosely coupled components
12. Each component goes through a well defined lifecycle, and hooks for intercepting important component events are available for application developers
13. Automatic (and fast) change detection mechanism spares you from the need to manually force UI updates while giving you a way to fine-tune this process
14. Angular 2 comes with the Rx.js library, which allows you to arrange a subscription-based processing of asynchronous data and eliminates the callback hell
15. Support of forms and custom validation is well designed
16. Unit and integration testing are well supported and you can integrate tests into your building process
17. The bundling and optimization of the code with Webpack (and its multiple plugins) makes the size of deployed application small
18. An ability to pre-compile the code eliminates the need to package Angular compiler (not to be confused with TypeScript compiler) with your app, which further minimizes the overhead of the framework
19. Angular Universal turns your app into HTML in an offline build step, that can be used for server-side rendering, which in turn greatly improves indexing by search engines and SEO
20. The library of the modern-looking UI components (Angular Material 2) is in the works
21. The scaffolding and deployment tool (Angular CLI) is in the works, and it will spare developers from writing the boilerplate code and configuration scripts

From the management perspective, Angular 2 is appealing, because there are already more than a million AngularJS developers, and most of them will switch to Angular 2. Having a large pool of workers with specific skills is an important consideration for selecting a technology for new projects. Besides, there are more than 15 million Java and .Net developers combined, and many of them will find the syntax of TypeScript a lot more appealing than JavaScript, because of support of classes, interfaces, generics, annotations, class member variables, private/public variables, helpful compiler, and good support by familiar IDEs.

As you can see from this list, Angular 2 comes with batteries included. Check it out!

Starting an Angular 2.0 project

After two years of development Angular 2.0 Final has been officially released on September 14, 2016. In this blog I’ll describe how to create your first Angular 2 project.

During the last couple of months Angular 2 was substantially redesigned/improved in several areas.

Now the app consists of modules, where one is a bootable module that identifies the root component of your app and declares other modules, components, directive, pipes, providers, and routes that are used in this module. Now there is no need to repeat these artifacts in every component. A module is a class decorated with the @NgModule() annotation, and you declare all these artifacts there. For example, the bootable module of your app may look like this:

import { NgModule } from '@angular/core';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
// other import statements are omitted for brevity

@NgModule({
  imports: [
      BrowserModule,
      FormsModule,
      ReactiveFormsModule,
      RouterModule.forRoot([
        {path: '',                    component: HomeComponent},
        {path: 'products/:productId', component: ProductDetailComponent}
      ])
  ],
  declarations: [
      ApplicationComponent,
      CarouselComponent,
      FooterComponent,
      HomeComponent,
      NavbarComponent,
      ProductDetailComponent,
      ProductItemComponent,
      SearchComponent,
      StarsComponent
  ],
  providers: [
      { provide: LocationStrategy, useClass: HashLocationStrategy },
      ProductService
  ],
  bootstrap: [ ApplicationComponent ]
})
export class AppModule {}

Only the bootable module can be BrowserModule. If your app uses several module (e.g. ShipmentModule, BillingModule, FormsModule, HttpModule), those modules are called feature modules are based on the CommonModule instead of the BrowserModule. Each of the feature modules can be loaded either eagerly when the app starts, or lazily, e.g. when the user clicks on the Shipping link.

The code of your app can be compiled either dynamically or statically. If it’s dynamically compiled in the browser, this is called just-in-time compilation (JIT). If the code is precompiled, it’s called ahead-of-time (AoT) compilation. I’m talking about the Angular compiler-cli (ngc), and not just transpiling from TypeScript to JavaScript here. A half of the size of a small app is the angular compiler itself, and just by using the AoT you’re app becomes slimmer because the compiler won’t be downloaded to the browser. One of the reasons the modules were introduced is that it helps the Angular compiler to know which artifacts has to be compiled for the module.

In this blog we’ll use the JIT compilation, and I’ll show you how to start a new Angular 2 project (managed by npm) from scratch without using the scaffolding tool Angular-CLI.

To start a new project, create a new directory (e.g. angular-seed) and open it in the command window. Then run the command npm init -y, which will create the initial version of the package.json configuration file. Normally npm init asks several questions while creating the file, but the -y flag makes it accept the default values for all options. The following example shows the log of this command running in the empty angular-seed directory.

$ npm init -y
 
Wrote to /Users/username/angular-seed/package.json:
 
{
  "name": "angular-seed",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Most of the generated configuration is needed either for publishing the project into the npm registry or while installing the package as a dependency for another project.

Because we’re not going to publish our app into the npm registry, you should remove all of the properties except name, description, and scripts. The configuration of any npm-based project is located in the file package.json, which can look like this:

{
  "name": "angular-seed",
  "description": "A simple npm-managed project",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

The scripts configuration allows you to specify commands that you can run in the command window. By default, npm init creates the test command, which can be run like this: npm test. Let’s replace it with the start command that we’ll be using for launching a web server that will feed our app to the browser. Several simple Web servers are available, and we’ll be using the one called live-server that’s we’ll add to the generated package.json a bit later. Here’s the configuration of the scripts property:

{
  ...
  "scripts": {
    "start": "live-server"
  }
}

While the start command is one of the pre-defined commands in npm scripts, and you can run it from the command window by entering npm start. Actually, you can define and run any other command that would serve as a shortcut for any command you could run manually, but in this case you’d need to run such command as follows: npm run mycommand.

Now we want npm to download Angular to this project as a dependency. We want Angular with its dependencies to be downloaded to our project directory node-modules. We also want local versions of SystemJS, live-server, the TypeScript compiler, and any other third-party libraries that our app needs.

So let’s add the dependencies and devDependencies sections to the package.json file so it’ll include everything that a typical Angular 2 app needs:

 {
  "name": "angular-seed",
  "description": "My simple project",
  "private": true,
  "scripts": {
    "start": "live-server"
  },
  "dependencies": {
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/core": "2.0.0",
    "@angular/forms": "2.0.0",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/router": "3.0.0",

    "core-js": "^2.4.0",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.37",
    "zone.js": "0.6.21"
  },
  "devDependencies": {
    "live-server": "0.8.2",
    "typescript": "^2.0.0"
  }
}

Now run the command npm install on the command line from the directory where your package.json is located, and npm will download the preceding packages and their dependencies into the node_modules folder. After this process is complete, you’ll see a couple of hundred (sigh) of directories and subdirectories subdirectories in the node_modules dir, including @angular, systemjs, live-server, and typescript.

angular-seed
├── index.html
├── package.json
└── app
└── app.ts
├──node_modules
├── @angular
├── systemjs
├── typescript
├── live-server
└── …

In the angular-seed folder, let’s create a slightly modified version of index.html with the following content:

<!DOCTYPE html>
<html>
<head>
  <title>Angular seed project</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script src="node_modules/typescript/lib/typescript.js"></script>
  <script src="node_modules/core-js/client/shim.min.js"></script>
  <script src="node_modules/zone.js/dist/zone.js"></script>
  <script src="node_modules/systemjs/dist/system.src.js"></script>
  <script src="systemjs.config.js"></script>
  <script>
    System.import('app').catch(function(err){ console.error(err); });
  </script>
</head>

<body>
<app>Loading...</app>
</body>
</html>

The script tags load the required dependencies of Angular from the local directory node_modules. Angular modules will be loaded according to the SystemJS configuration file systemjs.config.js, which can look as follows:

System.config({
    transpiler: 'typescript',
    typescriptOptions: {emitDecoratorMetadata: true},
    map: {
      '@angular': 'node_modules/@angular',
      'rxjs'    : 'node_modules/rxjs'
    },
    paths: {
      'node_modules/@angular/*': 'node_modules/@angular/*/bundles'
    },
    meta: {
      '@angular/*': {'format': 'cjs'}
    },
    packages: {
      'app'                              : {main: 'main', defaultExtension: 'ts'},
      'rxjs'                             : {main: 'Rx'},
      '@angular/core'                    : {main: 'core.umd.min.js'},
      '@angular/common'                  : {main: 'common.umd.min.js'},
      '@angular/compiler'                : {main: 'compiler.umd.min.js'},
      '@angular/platform-browser'        : {main: 'platform-browser.umd.min.js'},
      '@angular/platform-browser-dynamic': {main: 'platform-browser-dynamic.umd.min.js'}
    }
});

The app code will consist of three files:
– app.component.ts – the one and only component of our app
– app.module.ts – The declaration of the module that will include our component
– main.ts – the bootstrap of the module

Let’s create the file app.component.ts with the following content:

----
import {Component} from '@angular/core';
 
@Component({
    selector: 'app',
    template: `<h1>Hello {{ name }}!</h1>`
})
export class AppComponent {
    name: string;
 
    constructor() {
        this.name = 'Angular 2';
    }
}

Now you need to create a module that will contain our AppComponent. This code we’ll place inside the app.module.ts file:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }  from './app.component';
 
@NgModule({
    imports:      [ BrowserModule ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

This file just contains the definition of the Angular module. The class is annotated with @NgModule that includes the BrowserModule that every browser must import. Since our module contains only one class, we need to list it in the declarations property, and list it as the bootstrap class.

In the section packages of the SystemJS config file we mapped the name app to main.ts that will look like this:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }  from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

The last line of the above script actually compiles and loads the module.

Start the application by executing the npm start command from the angular-seed directory, and it’ll open your browser and show the message “Loading…” for a second, followed by “Hello Angular 2!”.

You can find the source code of our angular-seed project at https://github.com/Farata/angular2typescript/tree/master/chapter2/angular-seed.

A grouchy writeup on the Angular 2 situation

I decided to write this blog after reading an excellent comparison of AngularJS and Angular2. But today I’d like to talk about another aspect: how Angular 2 is being marketed and delivered to us.

When I started learning Angular 2 in Spring of 2015, it was clear to me that Angular 2 to AngularJS is as ham is to hamster (yes, I’m rephrasing a popular Java to JavaScript comparison). More than a year later, I still think that these are two different animals.

AngularJS 1.x was and still is the most popular JavaScript framework, and more than one million (!) developers are using it today. I guess someone at Google decided to capitalize on the popular brand and this is how the concept of the new version of AngularJS came about. Overall I think it was a smart marketing decision, which was supported by the fact that the creator of AngularJS and Angular 2 was the same rock star software engineer Misco Hevery. But rock star software engineers do create different products.

If Microsoft would use the same marketing strategy, they would not use the name TypeScript for the new language but would market it as C# 2. Both of these languages were created by Anders Hejlsberg, right? Then they’d publish a migration guide from C# to C# 2 similar to the migration path from AngularJS to Angular 2. I’m sure next year we’ll see more guides explaining how to migrate your app to Angular 2 from React, Ember, and ExtJS, and each of these migrations will be an effort similar to upgrading from AngularJS to Angular 2.

All right, let’s move from naming the framework to naming the releases. While writing the book we created multiple sample apps and had to change all of them each time when the new alpha release of Angular 2 was made available. This was expected and we survived a couple of dozen of such releases. Early this year the framework went to the beta phase, and in May of 2016 the Release Candidate 1 was announced.

If someone would ask me in January if it’s safe to start developing new apps in Angular 2, I’d say “Yes, it’s pretty stable now”. Boy, I was wrong! I always thought that alphas are for introducing new features and breaking APIs, betas are for fixing bugs, and release candidates are just for polishing things up. Who would expect that between RC.1 and RC.5 the router and forms API would be completely rewritten, and a new API (modules) would be introduced for packaging/loading apps?

If you’d ask me today (August 22, 2016) if it’s safe to start new development in Angular 2, I’d answer “If Angular 2.0 won’t be officially released in September of 2016, don’t bother.”

Go to StackOverflow and you’ll see that people are asking questions like “I’m having problems with so and so. I’m using Angular 2 RC.1”. If someone would suggest to upgrade to the latest RC.5, a typical answer would be, “Sorry, I have no time for this”.

Does it really have to be that time consuming to upgrade from one RC to another? Apparently it can be. There is even a guide titled “RC4 to RC5 migration“. It has an optimistic subtitle “Migrate your RC4 app to RC5 in minutes.” Yeah, right! This is exactly what I’m doing now. I’ve allocated a week to upgrade about 40 small apps from RC.4 to RC.5.

In the JavaScript community most of the software never reaches version 0.5. Announcing a Release Candidate of any JavaScript-related software sends the following message to enterprise developers: “This software is stable and it’s safe to start using it for the real-world projects”.

From a recent Adventures in Angular podcast I’ve learned that to decide if the next breaking change should be introduced in the next RC, the members of the Angular team ask themselves, “Would this make Angular better?” If the answer is Yes, they break the API.

A Popular Russian comedian Mikhail Zhvanetsky once said, “Who cares about the borscht if so much is going on in the kitchen!” Dear Angular team, I really like Angular 2 RC.5 as it is. Please concentrate on fixing bugs and stop cooking the borscht! Give us a stable release that won’t dramatically change for six months so we can release our apps too.

The happy ending

Angular 2 is a powerful platform for building complex suites of app. Being a Java developer for the most of my professional life, I can see that Angular 2 can make an effect in the JavaScript community similar to what Spring Framework made in the Java world, which was huge!

Keep in mind that there are about 15 million of Java and .Net devs, and most of them have not tried Angular 2 yet, but when they will, they’ll love it too!

I used AngularJS but never liked it. I knew it was the most popular JavaScript framework, but I never liked it anyway. As a matter of fact, I never liked neither JavaScript nor any other JavaScript framework. But I really like the Angular2/TypeScript duo!

Looking forward to hearing the following announcement at the AngularConnect 2016, “Ladies and Gentlemen, We’re happy to announce the release of Angular 2 1.0 today!”

Angular 2: Working with auxiliary routes

In the previous blog we learned that a child route is represented by a URL that consists of parent’s and child’s segments. Our small single page app had a single tag <router-outlet> where Angular would render the component configured for either parent or the child. The next subject to discuss how to configure and render sibling routes, i.e. the ones that are rendered in separate outlets at the same time. Let’s see some use cases:

* If a Gmail Web client displays the list of emails in your input mailbox and you decide to compose a new email, the new view will be displayed on the right side of the window and you’ll be able to switch between the inbox and the draft of the new email without closing either view.

* Imagine a dashboard-like SPA that has several dedicated areas (outlets) and each area could render more than one component (one at a time). The outlet A can display your stock portfolio either as a table or as a chart, while the outlet be shows either the latest news or the advertisement.

* Say we want to add to an SPA a chat area so the user can communicate with a customer service representative while keeping the current route active as well. Basically we want to add an independent chat route allowing the user to use both routes at the same time and switch from one route to another.

In Angular, you could implement any of these scenarios by having not only the primary outlet, but also the named auxiliary outlets, which are displayed at the same time with the primary one.

To separate rendering of components for a primary and an auxiliary routes you’ll need to add yet another tag(s) <router-outlet>, but this outlet has to have a name. For example the following code snippet defines a primary and a chat outlets:

<router-outlet></router-outlet>
<router-outlet name="chat"></router-outlet>

Let’s add a named route for a chat to our sample application.The snapshot below illustrates two routes opened at the same time after the user clicked on the Home and then on the Open Chat links. The left side shows the rendering of the Home component in the primary outlet, and the right side shows the Chat component rendered in a named outlet. Clicking on the Close Chat link will remove the the content of the named outlet.

ch3_basic_routing_aux

We added an HTML <input> field to the HomeComponent, and a <textarea> to the ChatComponent so it’s easier to see which component has a focus when the user switches between the home and chat routes.

Note the parentheses in the URL of the auxiliary route http://localhost:8080/#home/(chat). While a child route is separated from the parent using the forward slash, an auxiliary route is represented as a URL segment in parentheses. This URL tells us that home and chat are sibling routes.

The corresponding code that implements this sample is located in the file main_aux.ts and it’s shown next. We keep all the required components in the same file for simplicity. Both HomeComponent and ChatComponent have inlined styles to allocate them next to each other in the window. The HomeComponent is styled to get 70% of the available viewport width, and the ChatComponent will get the remaining 30%.

import {Component} from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

@Component({
    selector: 'home',
    template: `<div class="home">Home Component
               <input type="text" placeholder="Type something here"/> </div>`,
    styles: [`.home {background: red; padding: 15px 0 0 30px;  height: 80px; width:70%;
                    font-size: 30px; float:left; box-sizing:border-box;}`]})
export class HomeComponent {}

@Component({
    selector: 'chat',
    template: `<textarea placeholder="Chat with customer service"
                       class="chat"></textarea>`,
    styles: [`.chat {background: #eee; height: 80px;width:30%; font-size: 24px;
                     float:left; display:block; box-sizing:border-box;} `]})
export class ChatComponent {}

const routes: Routes = [
    {path: '',  redirectTo: 'home', pathMatch: 'full'},
    {path: 'home', component: HomeComponent}, // <1>
    {path: 'chat', component: ChatComponent, outlet:"aux"} // <2>
];

@Component({
    selector: 'app',
    template: `
        <a [routerLink]="['']">Home</a>
        <a [routerLink]="[{outlets: {primary: 'home', aux: 'chat'}}]">Open Chat</a> // <3>
        <a [routerLink]="[{outlets: {aux: null}}]">Close Chat</a> // <4>
        <br/>
        <router-outlet></router-outlet> // <5>
        <router-outlet name="aux"></router-outlet> // <6>
    `
})
class AppComponent {}

@NgModule({
    imports:      [ BrowserModule, RouterModule.forRoot(routes)],
    declarations: [ AppComponent, HomeComponent, ChatComponent],
    providers:[{provide: LocationStrategy, useClass: HashLocationStrategy}],
    bootstrap:    [ AppComponent ]
})
class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule);

1. Configure the route for Home component. Since no outlet is specified, the component will be rendered in the primary one.

2. Configure the route for Chat component to be rendered in the outlet named aux.

3. Render Home component in the primary outlet and Chat in the outlet called aux.

4. To remove the named outlet with its content give it a null value.

5. Declaring the primary outlet

6. Declaring an additional name outlet <router-outlet>. We named it aux.

If you want to navigate (or close) the named outlets programmatically use the method Router.navigate() as it was explained earlier in this chapter, e.g.:

navigate([{outlets: {aux: 'chat'}}]);

Hope this blog shed some additional lite on the very powerful Angular 2 router.

If you’re interested in learning Angular 2 in depth, enroll into one of our workshops. We’ll run the next public training   online starting from September 11, 2016. I can also deliver this workshop privately for your organization (send an email to training@faratasystems.com).

Angular 2 Hello World and the Guinness Book

How a programmer start learning new language or a framework? Right, by writing the Hello World app, which just prints a greeting. If it works, this means that you used the proper syntax and the environent is configured correctly.

This is how Hello World looks in JavaScript running in a browser:

document.write('Hello World');

In Java, Hello World is more verbose:

class helloWorld
{
  public static void main(String args[])
  {
    System.out.println("Hello World");
  }
}

In the Linux Assembly language it’s even more verbose:

 .text

 .global _start
 _start:

 mov $4, %eax 
 mov $1, %ebx 
 mov $msg, %ecx
 mov $msgend-msg, %edx
 int $0x80

 mov $1, %eax 
 mov $0, %ebx 
 int $0x80

 .data

 msg: .ascii "Hello World\n"
 msgend:

Let’s switch from languages to frameworks, which theoretically should let us write less code.

Using jQuery requires you to add to the HTML file one script tag and a couple of lines of JavaScript:

<!DOCTYPE html>  
<html>  
 <head>  
  <meta charset="UTF-8">  
  <title>jQuery</title>  
  <script src="http://code.jquery.com/jquery-2.2.3.min.js"></script>  
 </head>  
 <body>      
  <script>  
   $(document).ready(function() {  
    alert("Hello World!");  
  });   
});    
</script>  

 </body>  
</html>  

Now let’s see two more versions of Hello World:
1) Angular 2 (RC.5) and TypeScript
2) Angular 2 (RC.5) and JavaScript (ES5)

Hello World in TypeScript

The application itself will consist of two files:
index.html and main.ts. I’ll also add the Angular 2 framework with its dependencies, the Typescript compiler, and the SystemJS loader.

The index.html file is the entry point for the application. It will contain the references to the Angular framework, its dependencies, and the main.ts file, which contains the code to bootstrap your application. Some of these references can be located in the configuration file of the module loader.

Loading Angular in the HTML file

The code of the Angular 2 framework consists of modules (one file per module), which are combined into libraries, which are logically grouped into packages, such as `@angular/core`, `@angular/common`, and so on. Your application has to load required packages before the application code.

Let’s create an index.html file, which will start by loading the required Angular scripts, the TypeScript compiler, and the Sy Continue reading “Angular 2 Hello World and the Guinness Book”

Wrote a book on Angular 2. Do I know it?

Over the last year I spent a substantial portion of my time writing a book “Angular 2 Development with TypeScript”. I wrote it with my colleague, Anton Moiseev. We are already working on real-world projects in Angular 2 for our software product SureLC that automates the work of insurance agents. We also taught multiple public and private Angular 2 workshops.

This morning after reading yet another post titled “How to learn Angular 2?”, I’ve asked myself, “Do I know Angular 2?”. The honest answer is “Kinda”. Let me explain.

First, let’s define what a developer needs to know to be productive in an Angular 2 project. I’ll color the items as the slopes marked in the ski resorts.

Green – easy Almost flat
Blue – moderate. Can get nasty is the snow is not groomed
Red – difficult, but manageable for non-experts. The slopes are steeper than blue
Black – really difficult. You have to be an expert to enjoy the ride.

Disclaimer. I can ski on black slopes, but I don’t enjoy the process. You won’t enjoy watching me going down the black slope, but I’ll arrive to the base.

skii_map

1. TypeScript. Yes, you can use other languages, but let’s get real. The framework is written in TypeScript, 90% of blog post and tutorials use TypeScript.

2. NPM package manager. America runs on Dunkin. The JavaScript world runs on packages. If a C-programmer writes a function to pad a string with spaces, JavaScript programmer tries to find an NPM package that does it and adds it as a dependency to his application.

3. Type definition files (*.d.ts). These files help TypeScript compiler understand the API of third-party libraries written in JavaScript. Starting from TypeScript 2.0 it’s relatively easy with the @types npm organization.

4. A module loader. Starting from EcmaScript 6 we think in modules, and it’s a good thing. Adding and maintaining multiple scrip tags for dependencies? No more. You’ll start with SystemJS and then most likely will switch to Webpack.

5. Unit testing framework. Go with Jasmine.

6. Test runner that allows to run unit tests against multiple browsers from a command line. Use Karma runner.

7. Module bundler. You need to bundle your app into a small number of files so the browser won’t make several hundreds of network requests to load Angular modules. We use Webpack.

8. Task runner. Don’t even think of starting writing the app before setting up your build automation process. Start with using npm scripts. If you’ll run into any limitations, add some Gulp scripts.

9. Angular Router. This piece has been completely rewritten three times over the last year. It’s turning into a really powerful component.

10. Dependency Injection. Works really well and is stable.

11. Forms API. It’s still changing, but is getting there.

12. Inter-component communications. It’s important to architect your applications properly so components communicate in a loosely coupled way.

13. Reactive extensions RxJS. For async communications Angular 2 uses Observables and Subscribers instead of Promises.

14. The Http module. Responsible for communication with Http servers

15. Change detection (Zone.js). This piece monitors all async changes in your components and updates the view. For most apps you don’t need to worry about it, but if you’ll need to optimize the performance of your app, plan to invest some serious efforts to learn it.

16. UI components. Angular Material 2 is in its infancy with only 15 available components. If you need to deploy your app in prod this year, go with Wijmo 5 or PrimeNG

17. Angular CLI. This tool is in its infancy as well. It allows to quickly generate the project components and create the build. It starts with downloading the entire Internet to your computer and then generates stuff. My position is wait and see.

18. IDE. I saved this item for the happy ending. The IDEs used for TypeScript and Angular 2 are almost as good as their peers in Java or C# world. We use WebStorm, but Visual Studio Code is also great.

It took me a while to get comfortable with all the items from this list. I don’t know everything, but I know where to look for a solution. The Angular documentation is sparse and lots of APIs are not documented yet. There are multiple blogs that help with solving specific tasks, but most of the blogs become outdated because Angular 2 is still changing. In particular, the introduction of @NgModule in RC.5 forces me to refactor lots of code.

In the Summer of 2015 Angular 2 was in Alpha, the API was changing weekly, but I didn’t complain:  I was an early adopter. The problem is that it’s Summer of 2016, but as of Release Candidate 5 the API is still changing and I remain an early adopter.

This list may look intimidating, but if you’ll invest enough time the results will be rewarding. I believe in 2017 Angular will become the most popular framework for developing of the front end of the medium and large web apps.

If you’re interested in learning Angular 2 in depth, enroll into one of our workshops. We’ll run the next public training   online starting from September 11, 2016. I can also deliver this workshop privately for your organization (send an email to training@faratasystems.com).

Angular 2: Guarding routes

In this blog I’ll show you how to guard routes in Angular 2 Router (currently at 3.0.0-beta.2).

Let’s consider some scenarios that require a certain validation to be performed to decide if the user (or a program) is allowed to navigate to or leave the route:

* Allow to open the route only if the user is authenticated and authorized to do so.

* Implement a multi-part form that consists of several components, and the user is allowed to navigate to the next form section only if the data entered in the current one is valid.

* Remind the user about the unsaved changes if he or she tries to navigate from the route.

The router has the hooks that give you more control over the navigation to/from a route, and you can use these hooks to implement the any of above scenarios to guard the routes.

Angular includes a number of component lifecycle hooks that allow you to handle important events in the life of a component. First, it worth noting that the route configuration is done outside of the components. You configure routes in an object of type RouterConfig, then give it to the provideRouter() function, which in turn is given to the function bootstrap() that loads your app.
The type RouterConfig is a collection of items that conforms to the Route interface shown below:

export interface Route {
 path?: string;
 pathMatch?: 'full' | 'prefix';
 component?: Type | string;
 redirectTo?: string;
 outlet?: string;
 canActivate?: any[];
 canDeactivate?: any[];
 data?: Data;
 resolve?: ResolveData;
 children?: Route[];
}

While configuring routes you’ll typically use two properties from this interface: path and component. For example, an app that has two links Home and Product Details can specify and bootstrap the routes as follows:

bootstrap(RootComponent, [
    provideRouter([
      {path: '',        component: HomeComponent},
      {path: 'product', component: ProductDetailComponent}]),
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);

But in this blog I’d like to you to get familiar with the properties canActivate and canDeactivate that allow you to hook up the routes with the guards. Basically you need to write a function(s) implementing the validating logic that will return either true or false and assign it to one of these properties. If canActivate() of the guard returns true, the user can navigate to the route. If canDeactivate() returns true, the user can navigate from the route. Since both canActivate and canDeactivate properties of Route accept an array as a value, you can assign multiple functions (the guards) if you need to check more than one condition to allow or forbid the navigation.

Let’s create a simple app with Home and Product Details links to illustrate how you can protect the product route from the users who are not logged in. To keep the example simple, we won’t use an actual login service, but will generate the login status randomly.

We’ll create a guard class that implements the interface CanActivate, which declares only one function to implement: canActivate(). This function should contain the application logic that returns true or false. If the function returns false (the user is not logged in) the application will not navigate to the route and will print the error message on the console.

import {CanActivate} from "@angular/router";
import {Injectable} from "@angular/core";

@Injectable()
export class LoginGuard implements CanActivate{

  canActivate() {
      return this.checkIfLoggedIn();
  }

  private checkIfLoggedIn(): boolean{

      // A call to the actual login service would go here
      // For now we'll just randomly return true or false

      let loggedIn:boolean = Math.random() < 0.5;

      if(!loggedIn){
          console.log("LoginGuard: The user is not logged in and can't navigate product details");
      }

      return loggedIn;
  }
}

As you see from the code, my implementation of the function canActivate() will randomly return true or false emulating the user’s logged in status.

The next step is to update the router configuration so it uses our guard. The code snippet below shows how the function provideRouter() can look like for the app that has Home and Product Detail routes and the latter is protected by our LoginGuard:

provideRouter([
  {path: '',        component: HomeComponent},
  {path: 'product', component: ProductDetailComponent,
                    canActivate:[LoginGuard]}
])

Adding one or more guards to the array given to the canActivate property will automatically invoke all guards one after the other. If any of the guards returns false, the navigation to the route will be prohibited.

But who will instantiate the class LoginGuard? Angular will do it for us using its dependency injection mechanism, but you have to mention this class in the list of providers which are needed for injection to work. We’ll just add the name LoginGuard to the list of providers in the bootstrap() function of our app:

bootstrap(RootComponent, [
    provideRouter([
      {path: '',        component: HomeComponent},
      {path: 'product', component: ProductDetailComponent,
                        canActivate:[LoginGuard]}]),
    LoginGuard,
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);

The complete code of the main app script is shown next:

import {bootstrap} from '@angular/platform-browser-dynamic';
import {Component} from '@angular/core';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
import {provideRouter, ROUTER_DIRECTIVES} from '@angular/router';

import {HomeComponent} from './components/home';
import {ProductDetailComponent} from './components/product';

import {LoginGuard} from './guards/login.guard';

@Component({
    selector: 'basic-routing',
    directives: [ROUTER_DIRECTIVES],
    template: `
        <a [routerLink]="['/']">Home</a>
        <a [routerLink]="['/product']">Product Details</a>
        <router-outlet></router-outlet>
    `
})
class RootComponent {}

bootstrap(RootComponent, [
    provideRouter([
      {path: '',        component: HomeComponent},
      {path: 'product', component: ProductDetailComponent,
                        canActivate:[LoginGuard]}]),
    LoginGuard,
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);

If you run this app and will try to lick on the Product Details link, it’ll either navigate to this route or print the error message on the browser console depending on the randomly generated value in the LoginGuard. The snapshot below was taken after the user tried to click on the Product Details link, but the LoginGuard “decided” that the user is not logged in.

ch3_loginguard

But if our unpredictable LoginGuard “decided” that the user is logged in, the screen will look as follows after clicking on the Product Details link:

nonguarded

Dependency Injection Benefit. Since a guard is injected into your app, you can use it as any other object. For example, you can inject it in your RootComponent:

 constructor (private _loginGuard:LoginGuard){}

Then invoke any methods defined on the guard class, e.g.:

 this._loginGuard.changeLoginStatus(true);

Our LoginGuard implements the method canActivate() without providing any arguments to it. But this method can be used with the following signature:

canActivate(destination: ActivatedRouteSnapshot,
            state: RouterStateSnapshot)

The values of the ActivatedRouteSnapshot and RouterStateSnapshot will be injected by Angular automatically and may become quite handy if you want to analyze the current state of the router. For example, if you’d like to know the name of the route the user tried to navigate to, this is how to do it:

canActivate(destination: ActivatedRouteSnapshot,
            state: RouterStateSnapshot) {

      console.log(destination.component.name);
   ...
}

Implementing the CanDeactivate interface that would control the process of navigating from a route works similarly. Just create a guard class that implements the method canDeactivate(), for example:

import {CanDeactivate, Router} from "@angular/router";
import {Injectable} from "@angular/core";

@Injectable()
export class UnsavedChangesGuard implements CanDeactivate{

    constructor(private _router:Router){}

    canDeactivate(){
      return window.confirm("You have unsaved changes. Still want to leave?");
    }
}

Don’t forget to add the canDeactivate property to the route configuration and inject the new guard in bootstrap(), e.g.:

bootstrap(RootComponent, [
    provideRouter([
      {path: '',        component: HomeComponent},
      {path: 'product', component: ProductDetailComponent,
          canActivate:[LoginGuard], canDeactivate:[UnsavedChangesGuard]}
    ]),
    LoginGuard, UnsavedChangesGuard,
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);

For a fancier way of displaying confirmation dialogs use the MdDialog component from the Material Design 2 library (see https://github.com/angular/material2). This component will be released in the upcoming Alpha 8.

NOTE: If you want to delay the navigation to a route until certain data structures have been populated, use the property resolve from the Route interface. I’ll write a separate blog showing how to do it.

In this blog I didn’t show you the code of HomeComponent and ProductDetail component, but you can find them in the Github repo with the code samples from Chapter 3 from our book Angular 2 Development with TypeScript.

If you’re interested in learning Angular 2 in depth, enroll into one of our workshops. The next one we’ll run online starting from September 11, 2016.