Upgrading a Legacy Angular Web App

TLDR – it was the Spring of 2020 and one of my company’s web properties was on the final version of Angular 4. At the time of this writing Angular 9 had already been in production and I thought hey, why not go all in and address some technical debt with a modest upgrade from v4 to v6. Expectations and reality intervened and I upgraded to v5 instead.

Getting from here…


I finally had a window of opportunity to do an upgrade on an original Angular 2 app I developed in 2017 and I wanted to capitalize on that period of time to finally get the web app closer to the modern day benefits newer versions of Angular showcased (e.g. Angular CLI, Webpack as a module bundler, ahead of time compilation, tree shaking, etc.).

I had done upgrades for this web app in the past (e.g. 2.0 ➡ 2.4 ➡ 4.0 ➡ 4.7) but in my heart of hearts I knew this was going to be different as the Angular Team’s opinion on how to build their web apps became standardized. To ensure these notions I went head first into StackOverflow to field opinions outside of my own and two bold statements from the community said it all:

This is not trivial.


Man… no shortcut.


First Pass

So here I am, shooting for the stars and immediately I knew that if I wanted to do this, I’d have to go head first into the Angular CLI and bootstrap the foundations of this app in that fashion. I already had a seed project in a separate repository just in case I had the chance to do this. That, plus the guidance of Angular Update Guide, I felt compelled and ready to go.

In my view, I would be checking off every applicable box and then could immediately leverage the little things I’d been reading about for so long. Kickstart a localhost quickly, generate components and services dynamically with a select few keystrokes and allowing for Webpack to take lead in bundling up the final artifacts.

My first impressions were promising but as I immediately copy pasted the old code base over you immediately saw breaks. Localhost would not compile for a collection of different reasons which would scream in red on the command line. On the basis of that alone, I knew this was going to be an upward climb. Rather than focusing on the screams, I became more enamored with understanding the tooling behaviors versus addressing the core problem on hand – simply make the app work. To me, trying to flex that much CLI in one go was a bit egotistical and I was just too distracted. I lost time on this alone and I should have just played dumb in the short term and invested my time on the errors on hand.

The Gotchas

httpClient vs. HttpClientModule

If you’ve wrapped your web app with reusable services to perform the HTTP calls, you’re in for a treat when replacing httpClient in favor of HttpClientModule. In my case, I had to go through all of the necessary services and double-check how I was returning the response and error from the backend because JSON is now defaulted as the object to return back to the component. This means that any component which performs a subscribe() call should no longer evaluate the response or error through JSON.parse() methods.

SystemJS vs. Webpack

The original bundler, SystemJS went hand-in-hand with GulpJS as its task runner to perform the final build. Webpack’s bundler is completely stand alone. That in itself, was demanding to reconfigure. So heads up, if you’re going all in with rewriting that portion – it’s not straightforward. I parked this effort. I didn’t have enough time.

Starting From Scratch – WHY?!

What probably got me undone was how wide of a gap v4 was to v6. After several headaches, I needed insight outside of my own. And after consulting with another developer it was best to scrap such a tall order in favor of something more achievable. What undid me as well (although I still recommend doing it this way) was the fact that I kept a separate repository. At first pass, I needed to do it that way in order to fully see how a modern day Angular app gets built. Visually, it was easier to see how a project was seeded and with code structures pre-populated (e.g. App Module, Components, etc.), it was easier to digest. But alas, once I started porting the old code over, line-by-line fixes proved cumbersome.

My road to Angular 5 began immediately. Under that notion, I maintained the original repository (and all its commit history) and updated package.json accordingly with v5 specifications. Out of gas, I said f*ck it. Let it ride.

Next Pass

I scoped the original effort for a single two-week sprint. It spilled over immediately into the next but I knew I was close since localhost was working flawlessly under v5 updates. Now, it was a matter of smashing through the interactions, component by component. I checked off whatever applicable boxes were advised from Angular Update Guide and for the most part, tackling through httpClient was the majority of the dirty work. Improbable turned into tedious yet manageable.

Naturally, the bugs surfaced. But most of the bugs occurred due to previous implementations of the legacy httpClient. That said, it would not have been as obvious if existing coverage was not in place. When bugs were reported, it led to faster diagnosis and turnaround time on tightening up the screws. Some DevOps tweaking had to be done (NodeJS upgrade from v10 to v12, namely) but thankfully there was nothing on that side which led to extreme hardships.

One thing I forgot to mention was the topic of testing. Prior to this, I already had the luxury of having a test automation engineer provide existing code coverage on production. This was my insurance policy. I knew before hand having that coverage empowered me with enough runway to perform an upgrade.


I knew this wasn’t going to be cake – it was by far the most difficult upgrade path because of what other dependencies had to ship along with it. It took 1 sprint and 1 day to get this loaded into an environment. In hindsight, had I not involved myself with v6 and just stuck to a v5 upgrade, it would have been half a sprint and 1 day, tops. I know there are a few stones left unturned (currently not all in on the Angular CLI, SystemJS is still the module bundler, etc.). But hopefully, this puts the web app and any future developer who inherits this code into closer opportunities with modern day Angular capabilities.

I wrote this post with hopes of reaching out to JavaScript Developers facing similar constraints. You might be hired to work on a legacy app. You might be a team of one. You might not have the luxury of starting a project from scratch. Whatever the obstacle may be, I hope you pull the value you need from this story. If you feel that the tech moves extremely fast but the tech articles move even faster, you aren’t alone. Those tempos won’t necessarily match the speed and decision making of your business owners but that’s not a penalty on them. It’s on us and it’s the premium we pay for working on this side of technology.

For what it’s worth, my advice is this—take a moment to reflect and do the following below.

First, before thinking of performing such serious upgrades ask yourself about the current state of your test coverage. If you aren’t confident, prioritize that now. Yes, it’s a feat, but imagine if you didn’t have that in your back pocket. Next, don’t bet the house a.k.a do not skip versions. Then, define your incremental wins (e.g. v4 ➡ v5).

Finally – add up those wins and enjoy them. Reflect again. Rinse and repeat.

This article appeared on ISSUE 488 of JavaScript Weekly. I’ve found Cooper Press to be a great resource in sending out weekly emails pertinent to all aspects of web technology. If you haven’t yet, subscribe to them for FREE!

Puff Map

A quick and easy data visualization made for Puff Provisions LLC, a news and media company based out of Southern California.

This web asset illustrates the current state of Cannabis legalization throughout the USA.

This asset is powered by JavaScript charting library, D3.js.

Core Technologies

  • D3.js

Puff Finder

Utilizing previous techniques on creating a VueJS embeddable web app, I decided to propose the same for the Cannabis industry.

Meet Puff Finder – a web tool for filtering standardized data of cannabis seed companies, strains, brands, products, batches, retailers, and studies.

This asset was made for Puff Provisions LLC, a news and media company based out of Southern California.

Core Technologies

  • Vue CLI
  • Vuidget – Vue.js embeddable widget
  • Bootstrap 4, Bootstrap Vue
  • RapidAPI

SleepScore Article Generator

Considering REST API calls for WordPress were available since version 4.7, to me this was an opportunity to make a new experience. I wanted to consume blog posts and reuse them.

My approach was to consume those posts into an interface which could be cut and pasted to any web page. The empowering feature would be that the user could customize the colors of the widget with just a few clicks. So I created an Angular 6 proof of concept in 2018 which I positioned to be an affiliate marketing tool for SleepScore Labs. Do note, this app never went into production.

However, because of its ability to promote the brand from as easy as a copy/paste, it inspired business development to think about integrating SleepScore offerings in other ways.

In 2019, the creation of B2B sleep programs for companies promoting health and wellness to their employees was realized and a new revenue stream for SleepScore Labs was established.

Core Technologies

Article Generator

  • Angular 6
  • Angular PWA
  • Bootstrap 4
  • Gulp
  • Font Awesome
  • ngx color picker

Widget Embed

The code used via cut/paste also had to be built. The widget itself is a JavaScript embed. The logic is primarily DOM creation with jQuery alongside the Module Pattern as described by Addy Osmani.

SleepScore Animated Aura

A reusable JavaScript animation I developed for web and mobile platforms. This is currently the visual centerpiece of the SleepScore App available for FREE on iOS and Android.

The fundamentals for this were based on Addy Osmani’s explanation of The Module Pattern. A developer would call the object Aura and pass in an object literal of key-values to kickstart the animation. I used gulp for build tasks such as minifying code. Then each platform could host the final build artifacts on their respective app.

Core Technologies

  • jQuery v3
  • Sass
  • Gulp

Tap Cancer Out 2020 Results

After an individual campaign of $800+ it was time to get to work.

My attempted guillotine choke fails because I’m stuck in his half guard. That nullifies my leverage to properly place him on his back to position my wrapping arm.

I started out strong but was unable to maintain a dominant series and ended the match through points. There are several personal lessons for me on this one and as long as I am of sound mind and body, I will continue to pursue my development in Brazilian Jiu Jitsu.

That said, the overall event exceeded it’s goal with a final tally of $150K+. My donation page is still very much active, so please consider a donation to Tap Cancer Out which directly benefits Alex’s Lemonade Stand and their mission to change the lives of children with cancer through funding impactful research, raising awareness, supporting families, and empowering everyone to help cure childhood cancer.

Beat Cancer 2020

For 2020, I wanted to do my part in combatting cancer so I’m going head first personally in two campaigns. They are in no particular order – all are equally important. Please see below.


I met Mark by way of some old friends at the onset of my web development career. Mark, alongside some of my other awesome peers got me into things I thought I’d never do like playing Dungeons and Dragons. He’s my and many others personal Jeff Goldblum. I’m here letting you know that he needs our help. He’s in need of a bone marrow transplant and we’re looking for donors especially of Filipino 🇵🇭descent (where there’s a higher match of probability). Signing up for a kit and conducting a swab procedure could be the 15 minutes that saves his life. Please visit #makeyourmark77 and spread the word. Aloha 🤙🏾


In 2020, I’ll be fighting. However, this is no ordinary fight. I am taking part in the Tap Cancer Out BJJ Open and along with my teammates at Ribeiro Jiu Jitsu Carlsbad and competitors, I’ll be fighting for those who are in the fight of their lives –   children with cancer.

I’m raising funds in support of Tap Cancer Out, a 501(c)(3) charitable organization, and their beneficiary organization—Alex’s Lemonade Stand

Since 2012, tournaments like this one have helped Tap Cancer Out raise and donate more than $1.36 million for various cancer causes including the Leukemia & Lymphoma Society,  St. Baldrick’s, and the Pancreatic Cancer Action Network. 

I would be honored if you’d support my fundraising efforts with a donation. It’s secure and 100% tax deductible. If you’d prefer to pay by check, please mail to: Tap Cancer Out, 2 Enterprise Dr, Suite 307, Shelton, CT 06484.

If you can’t make a donation at this point, help me reach my goal by sharing this page on Facebook and/or Twitter! Or, even better, send an e-mail to friends you think might be interested in contributing and include a link to my page!

Thanks so much for your generosity!

SleepScore Cluster Analysis

A video walkthrough of a previously built Data Visualization Python Web App – enhanced with company branding, responsive layouts and shipped into Microsoft Azure Cloud. This tool was primarily intended for CES but feel free to view the Cluster Analysis Tool here!

Core Technologies

  • Bootstrap 4
  • jQuery
  • D3.js
  • Chart.js
  • Microsoft Azure
  • Python, Flask

SleepScore Sleep In America

A video walkthrough of a VueJS Data Visualization Web App I developed for SleepScore.com. This app acts as an embeddable widget so the codebase can be hosted on any domain or mobile app. The end user is able to compare and contrast sleep data based on region and gender. This was optimized mainly for iPad/tablet use cases for CES.

Core Technologies

  • Vue CLI
  • Vuidget – Vue.js embeddable widget
  • Vue Circle Progress
  • Bootstrap 4, Bootstrap Vue
  • jQuery
  • Google Charts