How to Migrate from Angular 1.x to Angular 2 in Simple Steps

BHARAT GUPTA

Why Migrate?

  • Better performance in Angular
  • Adequate support for mobile or smartphones
  • Keeping up with the latest tech
  • Straightforward and easier to learn

Upgrading using ngUpgrade

With ngUpgrade your Angular 1 codebase need not be migrated to Angular 2 all at once. We can do it gradually. ngUpgrade allows both Angular 1 and Angular 2 codebase to exist in the same project.

Let's get started.

  • Create a new Angular 5 project using angular cli.

ng new <project-name>

  • Install dependencies required for the upgrading from Angular 1 to 2 project.

npm install --save @angular/upgrade

  • Install all dependencies needed for the existing AngularJS project in the new project.

Example:
npm install --save angular @uirouter/angularjs

Hint: You can look up the package.json file of AngularJS app and find out the dependencies all at once. You would just need to install the ones in dependencies. Leave out the ones in devDependencies.

  • Copy all global CSS styles (typically from app/styles/app.css) of AngularJS project and paste it into app/styles.css of the new Angular project we created.
  • Copy all files from app directory (except global styles which you have already copied to app/styles.css) of AngularJS project to the app directory of the new project.
  • Make sure to import all the source files from AngularJS project into your new project before any other imports in main.ts file.
  • Change src/app/app.module.ts file with the following contents:

 

Angular 1 x to Angular 2 Migration_1.png

* make sure to update the root module name.

  • Build and host your application by running the command:

    ng serve

You should now have your AngularJS app bootstrapped and run by Angular.


Migrating to TypeScript

Identify the entities of an application (for example user, item, product etc) and create typescript interfaces for each one of them. Using typed interfaces can help you with intellisense and catching many errors at compile time rather than finding them at runtime.

You should use typed interfaces and classes for each component, directive, pipe etc.

So… what’s remaining?

Now we need to convert, one by one, all of our AngularJS entities (like directives, controllers, filters etc) to its corresponding Angular entity. The neat thing about doing this with UpgradeModule is that we can convert one module at a time and check if the app still works properly.

One must have a quick glance at the AngularJS to Angular Quick Reference guide before proceeding further with this document.

So, we need to convert each AngularJS module to respective Angular module. And for each module, we need to do the below steps.

  • Each AngularJS module to respective Angular module.
  • Element type directive to a Component.
  • Attribute type directive with a template to a Component.
  • Attribute type directive without a template to a Directive.
  • Find the set of controllers and templates in your routes and convert each of them to a component. If two different templates use the same controller, you must create two different components corresponding to each of the templates. However, make sure to move common business logic to an Injectable (aka service) to improve code reusability.
  • Convert a factory or a service to an Injectable (aka services)
  • Convert a provider too to an Injectable but using useFactory as specified in this section of Angular Docs.
  • Convert a filter to a Pipe.
  • Write all your run block code in a callback by chaining on the bootstrap method call of main.ts file. Example:
Angular 1 x to Angular 2 Migration_2.png
  • Config blocks are not a part of Angular anymore. All configuration happens in the providers section of a module.

After converting code for an AngularJS module to its equivalent Angular code, it might be needed that one of the converted component is used in the yet to be converted AngularJS module. To facilitate usage of Angular 2 component from  we need to downgrade the Angular component using the downgradeComponent function. The usage is exemplified here.

If the modules you want to inter-operate (i.e., you want to use Angular component from AngularJS) are tightly coupled then it is advisable to migrate both of them to Angular 2 without trying to bridge the gap by using downgradeComponent.

There might be cases where one component has already been upgraded to Angular >= 2.x, but it still uses Angular 1.x directives in its template. ngUpgrade allows us to use Angular 1.x directives in Angular 2.x components by upgrading them using upgradeNg1Component(). The usage is exemplified here.

Divide the routes between the Angular 1 and the Angular 2 routers

This section is taken from Victor Savkin’s blog.

If you are migrating small projects, you can migrate all the components in the application to Angular 2 first, and then rewrite all the routes in one go.

It, however, does not work with larger applications, which can have hundreds of routes. There you have to migrate routes module by module. And you can do it using the Angular 2 Router.

Let’s look at the settings module as an example. It has been fully migrated to Angular 2: everything, including the routes.

Screenshot-2018-7-16 Website_Angular 1 x to Angular 2 Migration (3).png

Wire it up in app.module.ts of the new Angular project by doing the following:

Screenshot-2018-7-16 Website_Angular 1 x to Angular 2 Migration (4).png

Where Ng1Ng2UrlHandlingStrategy is defined as follows:

Screenshot-2018-7-16 Website_Angular 1 x to Angular 2 Migration (5).png

Finally, update the root component to include an Angular 2 router outlet.

Screenshot-2018-7-16 Website_Angular 1 x to Angular 2 Migration (6).png

Remove Angular 1 when every module has been migrated

Once all the modules have been migrated, update the app.module.ts and main.ts files to remove all the usages of UpgradeModule.

That’s it!

This document just gives an outline of how the migration can be done. But there can be a few corner cases based on the project you want to migrate. Please update the document with the knowledge that you get while doing an actual migration. Cheers!!

Troubleshooting
@angular/core has no exported member 'StaticProvider'.

This happens because of version mismatch in the Angular project and the version of UpgradeModule being used. Make sure they are of compatible versions.

Error: AngularJS v1.x is not loaded!

This happens when we forget to load angularjs from the newly created Angular project. Make sure to import the angular dependency.

Module '<moduleName>' is not available!

We need to specify the appropriate root AngularJS module name in the bootstrap function of app.module of the new Angular project.

Resources:

https://angular.io/guide/upgrade

https://angular.io/guide/ajs-quick-reference

https://vsavkin.com/migrating-angular-1-applications-to-angular-2-in-5-simple-steps-40621800a25b

https://www.codementor.io/codementorteam/migrating-from-angular-1-x-to-angular-2-upgrade-strategies-a3fgzrhxo

https://blog.thoughtram.io/angular/2015/10/24/upgrading-apps-to-angular-2-using-ngupgrade.html