How to Migrate from Angular 1.x to Angular 2 in Simple Steps
- 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.
- 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.
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:
- make sure to update the root module name.
Build and host your application by running the command:
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:
- 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.
Wire it up in app.module.ts of the new Angular project by doing the following:
Where Ng1Ng2UrlHandlingStrategy is defined as follows:
Finally, update the root component to include an Angular 2 router outlet.
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.
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!!
@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.
'<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.