Migrate AngularJS to Angular using UpgradeModule (Part 4)

Danny Cornelisse

Part 1: Setting up the hybird app

Part 2: Refactor constants, values and services

Part 3: Refactor components

Part 4: Refactor directives

Part 5: Phase out angularJS services

Part 6: Remove dependent libraries and remove angularJS

Part 7: Deployment and build

Refactoring AngularJS to Angular

The previous steps explained how to set up the hybrid application (step 1), how to refactor constants, values and services (step 2) and how to refactor components (step 3). This next step will dive into refactoring angularJS directives to Angular components.

Refactoring directives

This chapter refers to attribute directives, not element directives. Treat element directives as Angular components and downgrade them to angularJS directives as described in the previous post.

Angular directives are always attribute directives. However, they cannot be downgraded to angularJS attribute directives. That means that when refactoring an angularJS attribute directive to an Angular directive, the Angular directive cannot be used in an angularJS html template. That is why angularJS directives should be refactored after refactoring components.

Attributes directives are very different in Angular than in angularJS. It might not be possible to achieve the exact same functionality in Angular directives. However, mostly it is possible. Things to consider:

  1. Binding to scope
  2. Lifecycle hooks, use ngOnInit, ngOnDestroy and constructor rather than link, (pre-)compile
  3. Reference the element: Import ElementRef from @angular/core to replace elem
  4. Reference the scope: Use the directive class: scope.property to public property
import { Directive,  ElementRef } from '@angular/core';

  selector: '[myHighlight]'
export class HighlightDirective {

  constructor(el: ElementRef) {
    el.nativeElement.style.backgroundColor = 'yellow';


Refactor unit tests

Refactoring unit tests requires more effort. Angular CLI ships with a karma and jasmine unit test configuration. However, it proves very difficult to support both angularJS unit tests and Angular unit tests during migration using ngUpgrade. However, it is certainly possible, although I failed to find a proper solution. Some of the solutions found in the online community:

  • Upgrading unit tests along-side components/services (Angular team)
  • Two separate karma configs:
    • One karma for angularJS unit tests
    • One karma for Angular unit tests (automatically configured by angular CLI)
  • Test helpers (possible new feature in Angular): https://github.com/angular/angular/pull/16848


The next part will detail how to phase out the remaining angularJS parts, such as angularJS native services.


you might also like