Brian Wagner | Blog

Following the Upgrade Path with Angular

Nov 30, 2018 | Last edit: Dec 31, 2020

The release of Angular caused quite a stir back in the fall of 2016. Like many, I jumped in and started learning the new framework, and how to build applications, complete with built-in routing, state management and build tools. Hacking away, I produced an app that started as something of personal interest but grew into more.

After the initial excitement, real life set in and I returned to my day job. In just two short years, Angular jumped from version 2 to version 7! And it was high time to begin enjoying all the enhancements and patch up some security issues that no doubt had emerged.

So, where to begin?

Framework upgrades are often tricky business, but the folks behind Angular have kept that in mind from the start. The switch from AngularJS to Angular was rocky, and few people wanted to endure that again.

Enter the upgrade guide.

https://update.angular.io/

Screenshot angular update site

Upgrades can be easy! And they can be guided. But not totally pain-free.

Angular 2.4 to 4

Based on the warnings I saw on the update guide and elsewhere, I didn't want to try jumping from Angular 2.4 all the way to 7. First make the leap to 4 and then maybe take a shot at jumping all the way to 7. In any case, it was worth the effort to migrate all the way to a current, stable release.

  • Angular 4 brought better integration with the router.
  • Angular 6 delivered improvements to the build chain.
  • Angular 7 had polished route guards and interceptors and it's faaaast.

The Angular guide allows you to set the original version and the target version, and then shows the relevant information. I have no idea what are the differences between 'Basic', 'Medium' and 'Advanced' levels of complexity. But choosing the 'Basic' level, I could quickly tick off the steps that were recommended:

  • "Ensure you don't use extends OnInit, or use extends with any lifecycle event. ..." NO.
  • "If you use animations ..." NO.
  • "Update all of your dependencies ..." YES.

Inside of the package.json, I stepped through the Angular and Angular-cli dependencies and manually changed the version numbers. There are a few core packages and they are listed separately in the manifest. Keep editing version numbers until the cli will build your app. Success!

Manually updating the package versions.

 "dependencies": {
-    "@angular/common": "^2.3.1",
-    "@angular/compiler": "^2.3.1",
-    "@angular/core": "^2.3.1",
-    "@angular/forms": "^2.3.1",
-    "@angular/http": "^2.3.1",
-    "@angular/platform-browser": "^2.3.1",
-    "@angular/platform-browser-dynamic": "^2.3.1",
-    "@angular/router": "^3.3.1",
+    "@angular/common": "^4.4.0",
+    "@angular/compiler": "^4.4.0",
+    "@angular/core": "^4.4.0",
+    "@angular/forms": "^4.4.0",
+    "@angular/http": "^4.4.0",
+    "@angular/platform-browser": "^4.4.0",
+    "@angular/platform-browser-dynamic": "^4.4.0",
+    "@angular/router": "^4.4.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.0.1",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.7.2"
  },
  "devDependencies": {
    "@angular/cli": "1.7.4",
-    "@angular/compiler-cli": "^2.3.1",
+    "@angular/compiler-cli": "^4.4.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "^6.0.42",
    "codelyzer": "~2.0.0-beta.1",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "2.5.0",
    "karma": "1.2.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-remap-istanbul": "^0.2.1",
    "protractor": "~4.0.13",
    "ts-node": "1.2.1",
    "tslint": "^4.0.2",
-    "typescript": "~2.0.3"
+    "typescript": ">=2.1.0 <2.4.0"
  }

Angular 4 to 7

That was the tedious part. From 4 to 7, it gets easier thanks to an update routine in the Angular-cli. A lot more happens, but the cli does the heavy lifting. Again, my app is in the 'Basic' complexity zone, so other apps may require more manual changes.

Two steps I had to take were migrating to Angular's new HttpClient module, and refactoring to use the pipe() operator in RxJS. Recall, Angular relies heavily on RxJS to make Http requests for example, so we have the changes in that dependency to accommodate.

The official Angular documentation suggests the HttpClient for general use, so it's straight-forward if you're just starting in Angular. And not a big leap if you're migrating from earlier versions.

As for RxJS, my code required me to change this:

let movies = this.http.get(this.baseUrl, {search: params})
  .map(this.convertMovies);

to look like this:

let resp = this.http.get(this.baseUrl, {params: param})
  .pipe(map(resp => this.convertMovies(resp)));

The Angular docs do a great job of getting you up and running quickly. Kudos to the docs team!

Maybe some of the most important things to come from the Angular team improvements are size and speed. Application size is way down, and that's even better with lazy loading. And application are fast. That should be the case going forward as well, as the engineers work on a new compiler called Ivy.

The current stable release of Angular is 7. But 8 is coming early next year. Looking at the update guide ... it doesn't suggest any pain points. And that's what we all want to hear.