Migrating your apps from AngularJS to Angular

So you have an Angular JS in prod and you want to migrate it to the latest version of Angular. The first question to answer is why? While talking to our clients, I’ve heard the following answers:

– We have a large app and it has issues with performance.
– Our company is moving to Angular/TypeScript and we want all apps to use these technologies.
– We need to improve performance of our AngularJS app
– Since all new apps will be written in Angular, it’s going to become hard to support apps written in two different languages and frameworks. The pool of developers who can/want write in AngularJS will be shrinking.

Any of the above answers sounds reasonable. But think about it for a moment. You have a working app with a certain functionality. After spending X amount of dollars your end users will get an app with the same functionality. Does it worth the trouble? Let’s say it does and the budget for the migration is approved.

Two approaches for migration

There are a couple of approaches to the AngularJS-Angular migration process.

1. Rewrite the app from scratch.

IMO, this is the best approach if your circumstances permit. A complete re-write can be the most cost-effective strategy. If you’re a manager, put your team through Angular training (live, online, videos, books). Allocate time and budget for getting your developers up to speed with Angular as the learning curve is steep and prior experience with AngularJS is not overly helpful. Then your developers will write the new version of the app as per best practices recommended for Angular/TypeScript projects. Ideally, your team should include a developer who has at least one year of practical development in Angular. If you don’t already have such a developer, hire one. He should be both a developer and a mentor.

But a complete rewrite may not be an option. Your existing (small-to-midsize) AngularJS app is in prod, works well, and the end users keep asking for new features that have to be released in prod on a regular basis. This means that you can’t just stop developing in AngularJS, and spending several months doing greenfield development is not an option.

You can’t do a complete rewrite if an existing app is large (think hundreds of views). In this case, a rewrite could take a couple of years.

2. Gradual migration

If you decide to go this route, start with reading the document titled “Upgrading from AngularJS“. It’s a well-written document, but you need to understand that it’s about migration from AngularJS to a completely different framework. Don’t be tricked by the statements like “Angular is a reimagined version of the best parts of AngularJS”. Angular is a different framework with different architecture and principles of building apps.

TypeScript, being a superset of JavaScript, requires some investment in learning too. But TypeScript is your friend. The learning curve for any JavaScript/Java/Python/C# developer is not steep, the tooling is great, optional static types make the transition from JavaScript easy plus you’ll get a great help from IDEs (autocomplete and compilation errors). In no time, you’ll see how your productivity is increased compared to writing in JavaScript.

Some die-hard JavaScript experts may continue bad-mouthing TypeScript, but be pragmatic. TypeScript allows making developers of any skill level (not just the superstars) more productive. Don’t trust me? A recent StackOverFlow survey nominated TypeScript as a third most loved language.

Plan your migration

You need to come up with a plan for your migration project. The plan will depend on how your current AngularJS app was written. While the Angular’s migration guide mentioned above recommends preparing your AngularJS app to have one component per file (see Rule 1 in the migration guide) and use module loaders, the chances are slim that your existing AngularJS app followed this rule. Refactoring your AngularJS app just to follow this rule is a project on its own; it may be costly and your refactored app would require additional testing and bug fixing.

The Angular migration guide explains how the AngularJS app should use component directives to simplify migration to Angular. Once again, changing your existing app to follow these guidelines is yet another project.

Depending on the production release schedule of the existing AngularJS app, you can pick one of two approaches for the migration:

– Feature by feature
– Route by route

When you migrate feature by feature, identify a group of component and services implementing this feature in the new Angular code.

Migrating route by route would also require a similar activity, but you’d need to pick a route and identify which components and services would need to be there. The route by route strategy works well if the views of your app are relatively simple and don’t use complex custom components.

If your AngularJS app has complex UI components, you may need to convert them first.

Running Angular and AngularJS side by side

The next step is to learn how the ngUpgrade and UpgradeModule work. The UpgradeModule serves as a bridge between the Angular and AngularJS parts of your app.

No matter how you’ll approach the migration, for some period of time your app will include two frameworks: AngularJS and Angular. When our company is involved with migration projects, we start with creating an Angular app that just bootstraps the existing AngularJS app as is with the help of the UpgradeModule.

With the UpgradeModule, you’ll run a hybrid app that’ll have two parts – one part will include Angular framework, and another – AngularJS. The components and services from the Angular part will communicate with their counterparts from the part written in AngularJS. Read the Angular migration guide about the differences in Dependency Injection (DI), change detection, and working with DOM.

While Angular DI is more flexible and allows either having services as singletons for the entire app or a specific component branch, in AngularJS services are always app-level singletons. This is not a big deal as in a typical Angular app we use app-level singletons anyway. In particular, you can use a singleton and DI for storing the state of the hybrid app. During the migration, you need to identify which services will be injected from Angular to AngularJS and those that will be injected in the opposite direction.

Components of both frameworks need to communicate with each other. If you’re not familiar with how to arrange a loosely-coupled component communication in Angular using injectable services, watch my video on the subject.

While running a mixed Angular/AngularJS app, the Angular framework will be responsible for triggering change detection of the entire app. Angular includes a library zone.js that serves as an execution context for all asynchronous processes of the app. On any change that may need to update a UI, it makes a single pass through the entire component tree and triggers the UI updates. There is no need to invoke $scope.$apply() as it’s done in AngularJS. In a hybrid app, on any async change that would start Angular change detection, the UpgradeModule will invoke $rootScope.$apply() in your AngularJS code.

Finally, roll-up your sleeves, start reading the AngularJS code and gradually implement it in Angular.

Automating deployment

Don’t forget about re-thinking your deployment process. Most likely you have an automated deployment implemented using Gulp or Grunt. In Angular apps most of the features that we had to manually configure in AngularJS are provided by the tool called Angular CLI. We wrap Angular CLI commands into npm scripts and add Gulp tasks if need be. It takes only several lines of code in npm scripts to build the bundles for deployment in Angular. In this video I show how to write a script that will build the Angular bundles and deploy them under a Java Spring server. If I wanted to gzip the files before deployment, I could have added one more line like `“postbuild:prod”: “gulp –gulpfile compress.js”` that invokes my script that uses the Gulp plugin for compression.

Good luck with your migration projects!

Advertisements

Angular 2: What’s with the name?

The Angular 2 framework now supports semantic versioning, and it was announced that major upgrades (with breaking changes) will be released twice a year. In particular, in March of 2017 the version 4.0.0 will be released, in September – 5.0.0 and so on.

This is all good but the problem is that not only the versioning will be different, but Angular team is considering changing the name from Angular 2 to Angular. This will create lots of confusion in the Angular community.

First, a bit of history. The older version of this super popular Web framework is called AngularJS (currently at 1.6.0). Two years ago a complete redesign of this framework was announced, and the new framework got the name Angular 2. I guess, someone at Google suggested to keep the word Angular in the name to leverage the fact that more than 1.3 million of software developers were already using AngularJS, and most of these people would want to upgrade to the newer version of the same framework.

The problem is that Angular 2 is completely different framework, and suggesting the roadmap for upgrading existing AngularJS apps to Angular 2 is no different than suggesting a roadmap for upgrading an app from Ember or React to Angular 2. But the marketing plan worked out nicely, and more than 700K developers are using Angular 2 by now. No wonder – Angular 2 is a great framework.

People started creating Angular 2 communities to post articles, and ask for help. For example, the Reddit’s Angular 2 community is pretty active and has 6800 members: https://www.reddit.com/r/Angular2/. Questions and answers on StackOverflow are marked with the tag #angular2: http://stackoverflow.com/questions/tagged/angular2. LinkedIn has a group of 7900 Angular 2 developers: https://www.linkedin.com/groups/8434339.

Bloggers (myself included) are posting articles and tutorials that have Angular 2 in their names. PluralSight, Lynda.com, egghead.io and many independent developers produce video contend with Angular 2 in their titles.

Book authors (myself included) wrote about a dozen books with Angular 2 in their titles, and these books will remain relevant and useful for several years, unless Google will decide to completely re-write this framework again.

If the framework will be renamed to Angular, anyone searching for Angular 2 content will be inevitable getting materials for both AngularJS and Angular 2. Just try finding posts on StackOverflow tagged as Angular: http://stackoverflow.com/questions/tagged/angular. The “angular” in the URL will be automatically converted to “angularjs” and you’ll be seeing 200K+ irrelevant posts about AngularJS. IMO, it’s a disservice to the community. BTW, there is Angular Reddit group as well: https://www.reddit.com/r/angular, and these developers may want to keep their forum clean from Angular 2 posts.

I suggest to keep Angular 2 as the name of the framework. The digit 2 here won’t represent the version, but rather the next generation of this framework. So in March we’ll get Angular 2 v. 4.0.0, in September – Angular 2 v.5.0.0 and so on. Content producers can still include “Angular 2” in the titles and use the tag #angular2 in social networks.

What do you think?

P.S. The community may decide to keep using the tag #angular2 regardless of the official name of this framework.

Two-way Data Binding in Angular 2

By default Angular 2 doesn’t use a two-way data binding. It uses a unidirectional binding but if offers you a simple syntax for a two-way data binding if need be. In this blog I’ll show you an example of such syntax.

One-way binding from the UI an Angular component is arranged by surrounding an event name with parentheses:

<button (click)="onClick()">Get Products</button>

<input placeholder= "Product name" (input)="onInput()">

The one-way binding in the opposite direction is denoted by surrounding an HTML attribute with square brackets. The greeting is a property of an Angular component in this line:

<input [value]="greeting" >

There is also a template binding that allows to add/remove HTML elements to the DOM tree. The following line will add the only if a boolean flag is true, for example:

<span *ngIf="flag">Flag is true</span>

In limited cases you may want to use two-way binding, and you can specify it by adding the ngModel directive as an HTML attribute surrounded with both parentheses and square brackets, for example:

<input [(ngModel)] = "myComponentProperty">

In other frameworks two-way binding is popular with forms where you often needed to synchronize values of the form fields with the underlying model. While Angular also allows you to map each form field to the corresponding property of the model object there is a better way to handle forms and I’ll write about it in a separate blog. Still, there are some cases when using ngModel may be handy, so let’s get familiar with the syntax.

Say the landing page of a financial application allows the user to check the latest prices of the stock by entering its symbol in an input field. Often the user enters the same stock that he owns or follows, e.g. AAPL for Apple. You could save the last entered symbol as a cookie or using the HTML5 local storage, and next time the user opens this page the program reads it from there and populates the input field. The user still should be able to type in this field and the entered value should be synchronized with a variable lastStockSymbol, which plays the role of the model (as in MVC). The code sample below implements this functionality.

import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';

@Component({
    selector: 'stock-search',
    template: `<input type='text' 
        placeholder= "Enter stock symbol" [(ngModel)] = "lastStockSymbol"> // 1
               <br>The value of lastStockSymbol is {{lastStockSymbol}}`
})
class StockComponent {

    lastStockSymbol: string; // 2

    constructor() {
        setTimeout(() => { // 3            
            this.lastStockSymbol="AAPL"; 
        }, 1000);
    }
}
@Component({
    selector: 'app',
    directives: [StockComponent],
    template:`<stock-search></stock-search>`

})
class AppComponent {}
bootstrap(AppComponent);

1. Requesting the two-way binding to synchronize the changes in the input field with lastStockSymbol

2. The lastStockSymbol is our model and it can be modified either by user typing in the input field or programatically.

3. To emulate a scenario of reading the last stock symbol we simply arranged a one second delay after which the value of the variable lastStockSymbol will be changed to AAPL and the <input>> field will show it.

The variable lastStockSymbol and the value of the <input> field will be always in sync, and you can see this in action by trying it online on Plunker at http://bit.ly/1MDExS2. A little bit fancier version of this sample is located at http://plnkr.co/edit/bOOkz96iIjFu9ydHKNNy

In AngularJS 1.x the two-way binding was a default mode of operations, which seems like a simple and elegant solution for synchronization of a view and a model. But on a complex UI containing dozens of controls, where changing the value in one place could cause a chain of bindings updates performance could suffer.

Debugging could also be more difficult as there could be many reasons of why a particular value was changed. Was it because of the user’s input or it’s a result of modified value in seemingly unrelated variable in the program? With two-way binding implementing the change detection inside the framework was not trivial either. With the unidirectional data flow you always know where a change to a particular UI element or a component property came from. We’ll discuss Angular’s change detection mechanism in on of the future blogs.

My other Angular-related blogs are here. Manning is publishing the drafts of the book “Angular 2 Development with TypeScript“ that I write with Anton Moiseev. Starting on February 28, we’ll also teach an online class on Angular 2.

Recording of the Lesson “Intro to AngularJS”

Over the last years we’ve been teaching AngularJS for various audiences. Besides  traditional live instructor-led class for private clients, we (Farata Systems) teach 3-4 public trainings online each year. Typically we run these trainings on weekends allowing developers from around the world sharpen their skills without missing their daytime job.

To give you an idea how our online training classes work, I’ve published a 3-hour long video of the session introducing AngularJS that I ran for a group of Java developers in March of 2015. For privacy reasons I’ve replaced the names of the participants in the chat window with nicks. This was the second lesson in this training and I started it with a brief review of the homework given after covering JavaScript (ES5) in the first lesson.

In 2016 we’ll be offering a training class covering Web application development with Angular 2 and TypeScript. The enrollment to the class that starts on February 28th is open.