Featured

My training schedule

My scheduled Angular 2 training classes:

Online workshop on Angular 2, starts on September 11

* Private two-day Angular 2 workshop at Princeton University, Princeton, NJ September  13-14

* Private two-day Angular 2 workshop at Fedex, Memphis, TN September  19-20

* Angular Summit, Boston,MA Sep 26-28

*  Two-day public Angular 2 workshop, O’Reilly, Boston, MA September  29-30

* Rich Web Experience, Clearwater, FL, Dec 6-9

If you’d like me to run an Angular 2 workshop for your organization please send an email at training@faratasystems.com.

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.

Angular2, npm, and TypeScript: the first steps

Angular 2 is getting more and more stable. As of July of 2016 it reached the version Release Candidate 4 and I expect to see the official release of this framework not later than in October of this year.

While developing Angular 2 applications in TypeScript is easier than in JavaScript, the initial setup of the project may be intimidating. You need to be familiar with installing and configuring NPM packages and the process of transpiling of the code from TypeScript to JavaScript.

I’d like to offer you an extract from the video from the first session of our recent online training where I show how to install the TypeScript compiler, all required npm modules, and create configuration files for npm and the module loader SystemJS. In this video I was using Angular Release Candidate 1, but you can change the versions from rc.1 to rc.4 and everything will work fine.

Our next 6-week online workshop starts on September 11. It runs on weekends and will give you a solid understanding of how to work on the real-world project with Angular 2 and TypeScript.

If you’re reading this blog after September 11, check the schedule of our upcoming trainings at yakovfain.com.

Dear Publisher, please do not print our book

Disclaimer: I’ve been writing for many publishers and Manning’s process of book publishing is the best I’ve seen so far.

My colleague and I spent a year writing the book on Angular 2. At the same time the Angular team was releasing dozens of alphas, and we kept modifying the code and the text.

Then the Angular team released several betas of Angular 2, and we’ve modified the code and the text.

Then the Angular team released several Release Candidates of Angular 2, and we’ve modified the code and the text.

The good news. Manning has released six versions of MEAP of our book “Angular 2 Development with TypeScript”, which remains Manning’s bestseller for many weeks in a row.

We’re diligently updating the code and the text, but I don’t want this book to be printed on paper. Why? Because the Angular team (understandably) will keep changing the API, and the readers of the printed book will blame us for the outdated text.

This book as well as all other books on software should NOT be printed on paper. The authors should be able to keep changing drafts for as long as the software is being changed. If not printing is not an option, the publishers should offer a print-on-demand service for those readers who like paper.

Back to Angular 2. Over the last year the router has been re-written three times. The final re-write (known as Router 3.0) has been released AFTER the Release Candidate 1.

The Forms API has been changed (currently at 0.2.0) as well after the Release Candidate 1.

We write code in TypeScript, which is a great way to develop JavaScript applications with types support. To integrate the TypeScript code with tons of available JavaScript libraries we need so called type definition files (*.d.ts). There was a Type Definition manager tsd. It’s deprecated in favor of Typings. Cool. We changed everything to work with type declarations known as “ambient”. All of a sudden ambient no more. As of May 2016 it’s called “global”. OK. Changed the text and the code. But. If Manning will publish our book before TypeScript 2.0 is out, it’ll be outdated. Why? Because TypeScript 2.0 will introduce @types that will deprecate Typings.

There is more to whine about. Unit testing. It’s being changed as we speak. OK, we’ll re-write chapter 9 to remove anything specific to Jasmine.

Chapter 10. Build automation. We used Webpack cause it’s the tool to use for prod systems today. Meanwhile, Google shows wonders at the conferences with Angular CLI, which (I’m sure) will become the right way to automate builds of Angular apps. But not this year. At the time of this writing installing Angular CLI is like installing the whole content of npmjs.org. To put it simple, if you want to clone the entire NPM repo, write the following command: npm install -g angular-cli.

Now let’s talk about UI. The Material Design 2 is in the works. But. It has about 15 components now. Cool for demos and conferences, but not for the real world enterprise apps. It’s getting there, but not this year. So what you, the enterprise developer should do? Get Wijmo 5 components. It costs money and is not a silver bullet. But, there are not many choices as of yet.

Job offer. I got an email asking if I’m available for working on a two-month consulting project. The scope is to create an initial setup for Angular 2 projects, prepare the build scripts, and develop a library of reusable UI components. I can do all of this in two months except a library of reusable UI components. Sorry, I’ll pass on this opportunity. Get real. Next year. Maybe.

We’re running our ongoing training classes using our book as a textbook. This allows us to keep our training materials as well as Manning eBook up to date. But I hate to see the future comments pointing at the places where our printed text is wrong.

I used to own a large library of software books, but during the last year I threw away (left at the curb for recycling) about 50 books on software that were printed before 2011. Next month I’ll get rid of all books that were printed before 2014. Unless the book is about data structures or algorithms it’ll go to recycling.

I really like the Manning’s workflow in publishing books. But it’ll be even better if this book will never be printed. We already sold about two thousand e-book downloads. Let’s keep selling files, and we’ll keep them up to date. There is a MEAP program for drafts, and a similar program is needed to keep the drafts updated after the book is “finished”. Dear Manning, please do not print our book or print it on demand!

UPDATE: I had a chance to discuss this blog with Manning. This is what I was told:
1. When Manning sells a printed copy the reader gets the e-Book as well.
2. Their MEAP program can continue even after the books is printed as long as the authors are willing to keep the book up to date. We’re willing.
3. The book goes to printer in small batches, and if the content of the manuscripts has changed, the new print batch can have the new content (Manning can easily do this if page numbering doesn’t change).

I’m wondering what other publishers do to keep printed books current?