Necessary and Useful
Migration from AngularJS to Angular
Zürich, Apr 2019
In the summer of 2017, faced with Google’s announcement that it would be ending support of AngularJS, we decided to migrate our product, reclaimer®, from AngularJS to Angular. It was a significant task: we had a fairly large application, a new framework, and the added complexity of a hybrid approach.
Why would you want to ‘sink’ resources into migrating from AngularJS to Angular?
There is an inherent inertia associated with legacy products, systems, and applications which are running well but using outdated technology. Investing time and resources into simply refreshing a successful product can seem wasteful. Perhaps the most salient reason to migrate is that AngularJS will soon be deprecated (it is currently in ‘Long Term support’ until June 2021 at which point there will be no more support). This, therefore, gives limited time until AngularJS applications are unmaintainable. This announcement was the main driver behind our own migration.
Similarly, there is dying support from other developers in terms of libraries and other tools. During our own migration, we found that the tables we had been using were deprecated; we were unable to migrate them and had to completely rewrite from scratch. Overall, this supports the fact that AngularJS is an outdated technology in a fast-moving space; it simply can’t keep up. The efficiency of development and the quality of your application will both be improved by this transition, with applications written in AngularJS already looking dated and clunky. Not only is AngularJS becoming outdated, but Angular itself also provides a number of useful new features. The use of typescript, AngularCLI and ahead of time compilation, as well as many other features, can result in large efficiency gains.
Further, the longer you wait the greater the task will eventually be. Adding more features and complexity in AngularJS now will add time and cost to your later migration job. With an end-date set for AngularJS, continued development with that framework is wasteful and counterproductive. If you wish to add new features and updates to your application, this can be done during or in tandem with the migration process. This is a better allocation of resources than simply upgrading the AngularJS application due to the concrete end-date produced by Google. This limits the returns on any investment into AngularJS development.
Last but not least, as others move to Angular, your AngularJS applications may become incompatible. For instance, those on the Avaloq front platform (AFP) will need to migrate their customisation to remain compatible with the AFP when it transitions. This may be sooner than the AngularJS death-date.
There are three major methods of migration available depending on your application.
Starting from Scratch
The most obvious method is to simply start from scratch. If your application is clunky or unwieldy to begin with, with cumbersome code best rewritten, it may be advisable to start anew. Moreover, with complex applications, the learning curve and lack of documentation associated with the Hybrid method (see below) can cause troubles and slow progress. Starting from scratch may result in smoother workflow and fewer errors. Given no resource restrictions, allowing you to both maintain the old application and develop a new one from scratch in tandem using two teams, this may be sensible. However, it would tend to be quite inefficient. From Angular 1.5 onwards, code can be written in a similar style to Angular - the classes from AngularJS being comparable to the components in Angular - meaning that a Hybrid migration would reuse a significant amount. Moreover, if you do not currently have sufficient resources on hand to run two teams, new developers unfamiliar with the application will further slow the process.
This method uses both AngularJS and Angular alongside one another. By using ngUpgrade you can run both frameworks and wrap components for compatibility. This then allows you to migrate piece by piece, whilst staying online and maintaining your application. If you are running AngularJS 1.5+, using classes, this will make the transition even easier due to its similarity with Angular. The Hybrid method requires far fewer resources than starting from scratch since the application can be kept online with one team both maintaining and migrating. This will likely make it much cheaper. This also prevents the inexperienced developer issue faced by growing a team, sometimes necessitated by the ‘from scratch’ method. However, it is not without its problems. There is a serious lack of documentation, or online resources generally, regarding migration of a complex application from AngularJS to Angular. Moreover, what is available mostly focuses on the latest versions and writing styles of AngularJS. Those writing using functions rather than classes will likely run into many issues given the lack of support and incongruity of the styles. This results in a trial and error approach, where problems are fixed ad hoc with creative methods. Though this does work, it can be frustrating. Also, the wrapping functionality of ngUpgrade has a steep learning curve and is conceptually complex, which some developers may struggle with. This can lead to stagnant workflow and frustration.
Our own Experience
With the upcoming demise of AngularJS, we saw an opportunity to both future-proof and improve our reclaimer® product. Our developers wanted to work with modern tools and modern libraries which just simply can’t be done in AngularJS. We were already beginning to see support from the community dying; this was made worse by Google’s move to stop support by 2021. We, therefore, decided it was time to change.
After much deliberation, we decided to take the Hybrid approach feeling it the most effective way to tackle our problem, especially given our available resources. The reclaimer® is a medium sized banking application, of similar complexity to comparable applications. This, therefore, made it quite a significant task.
We began work in August 2017, initially building a small prototype to get to grips with the migration and with Angular; which, though similar, still had significant differences with AngularJS. Though useful, we soon realised the prototype exercise bore little similarity to the problem which faced us. The complexity of our app meant the difficulty of migration had grown exponentially. In uncharted waters, we entered a phase of trial and error. We learnt: how the migration would work, fixes, and solutions as we progressed. This was the most difficult phase, made worse by the lack of documentation or support. The resources which were available, such as Google’s guide to migration, were based on very simple applications written in the latest version of AngularJS. Since our application was based around functions rather than classes, there was a certain degree of mismatch in style and architecture, resulting in errors. For example, we originally designed the new application to have a single Angular root with a variety of AngularJS and Angular children (fig. 1). This caused significant performance issues. We found no documentation or support which explained this issue. Eventually, we added an AngularJS root with a single child, the Angular component (fig. 2). This solved the performance issue. Similarly, we faced an issue around the asynchronous loading of pages. Some pages had components which would load after the initial page was rendered. Though the request was made, the secondary loading was never rendered. This was solved; however, again, we found no explanation online. One of the most technically challenging tasks in this migration was the wrapping of components. In the beginning, this added complexity to the project as we got to grips with the tools, exacerbated by the myriad unexplained errors.
Migrating the app also caused some functionality to be completely rewritten. Tables which had been central to the original product had now become deprecated. This prevented us from simply migrating them, effectively forcing us to write these new components, from scratch, in Angular. We were also forced to rewrite our testing infrastructure. Since it was based on the old app architecture it would not work with the new structure.
We also took this exercise as an opportunity to improve our product. The styling of reclaimer® had begun to feel outdated when compared to other applications and platforms in the e-banking space. We, therefore, refreshed the styling. Moreover, we added greater functionality, such as a smart search function. Altogether, we feel this has led to an improved user experience.
With members of the team testing the app, looking for and solving errors, we developed a deep and comprehensive understanding of the migration process. By January 2018 we were able to ship to clients. Although it transpired we had not spotted all errors, we were quickly able to make hotfixes due to the skill-base we had developed over the previous 5 months. Migration is a continual process which is still occurring with regular updates. We aim to be fully migrated by the 2021 deadline.
Overall, we see a migration from AngularJS to Angular as both necessary and useful. It can help modernise and improve your application, resulting in greater user satisfaction. It is a complex process, one which some may have been wary of. If your product is reaching the limit of its profitability, the investment of time and resources may not reap sufficient a reward to warrant this allocation. However, weighing the multitude of benefits with the fact that Google support will be stopping soon, if you see a future with your application, now is the time to make the move! Our own path was initially plagued with errors. At times it was a struggle; however, after dealing with a few seemingly irrevocable errors we soon gained the skills and confidence to complete the job. We are wholly content to have made the move, now with a better product and greater experience.
Leiter Software Entwicklung