Missing dependencies in AngularJS to Angular migration

Loading

Migrating from AngularJS (1.x) to Angular (2+) is a significant transformation that introduces dependency management challenges. Missing dependencies can cause runtime errors, broken functionality, and failed builds.

This guide explains why dependencies go missing, common migration issues, and step-by-step solutions to resolve them.


1. Why Do Dependencies Go Missing?

When upgrading from AngularJS to Angular, dependencies may be lost due to:

  1. Different Dependency Injection (DI) Mechanism – Angular uses constructor-based DI, whereas AngularJS uses $injector and $provide.
  2. Module System Changes – Angular uses ES6 modules (import), unlike AngularJS, which relies on angular.module().
  3. Breaking Changes in Libraries – Some AngularJS libraries don’t have direct Angular equivalents.
  4. Package Renaming – Some third-party dependencies are deprecated or replaced in Angular.

2. Identifying Missing Dependencies

Error Messages Indicating Missing Dependencies

Error MessagePossible Cause
Error: [$injector:unpr] Unknown providerA service, factory, or module is missing
Module not found: Error: Can't resolveA package is missing in node_modules
No provider for <ServiceName>Dependency Injection (DI) issue
Cannot find module '<module-name>'The module is not installed or incorrectly imported
TypeError: Cannot read properties of undefinedA dependency is missing or incorrectly injected

3. Common Missing Dependencies and Fixes

A. Missing Angular Modules

When migrating to Angular, ensure all required modules are imported in app.module.ts.

Fix: Import Required Modules

import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
imports: [
CommonModule,
FormsModule,
HttpClientModule
]
})
export class AppModule { }
  • CommonModule – Required for built-in directives like ngIf, ngFor.
  • FormsModule – Required for template-driven forms (ngModel).
  • HttpClientModule – Required for making HTTP requests.

B. Missing Third-Party Packages

Third-party packages in AngularJS might not be compatible with Angular.

Fix: Install Required Packages

Run the following command to check missing dependencies:

npm list --depth=0

If a package is missing, reinstall it:

npm install <package-name>

Example:

npm install lodash
npm install moment

If the package does not support Angular, find its equivalent.

AngularJS PackageAngular Equivalent
angular-ui-router@angular/router
angular-resourceHttpClientModule
angular-sanitizeDomSanitizer

C. Missing Services Due to Incorrect DI Syntax

Angular uses constructor-based injection, whereas AngularJS uses $inject.

Fix: Correct Dependency Injection

Before (AngularJS Service Injection)

angular.module('app').service('MyService', function($http) {
this.getData = function() {
return $http.get('/api/data');
};
});

After (Angular Service Injection)

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class MyService {
constructor(private http: HttpClient) {}

getData() {
return this.http.get('/api/data');
}
}
  • Use @Injectable({ providedIn: 'root' }) to make services available application-wide.
  • Use constructor injection instead of $inject.

D. Missing Pipes and Filters

AngularJS uses filters, whereas Angular uses pipes.

Fix: Convert Filters to Pipes

Before (AngularJS Filter)

angular.module('app').filter('capitalize', function() {
return function(input) {
return input.charAt(0).toUpperCase() + input.slice(1);
};
});

After (Angular Pipe)

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'capitalize' })
export class CapitalizePipe implements PipeTransform {
transform(value: string): string {
return value.charAt(0).toUpperCase() + value.slice(1);
}
}

Now, import the pipe in the module’s declarations:

@NgModule({
declarations: [CapitalizePipe]
})
export class AppModule { }

E. Missing Directives After Migration

AngularJS custom directives don’t automatically work in Angular.

Fix: Convert Directives to Angular Components

Before (AngularJS Directive)

angular.module('app').directive('customButton', function() {
return {
restrict: 'E',
template: '<button>Click Me</button>'
};
});

After (Angular Component)

import { Component } from '@angular/core';

@Component({
selector: 'app-custom-button',
template: '<button>Click Me</button>'
})
export class CustomButtonComponent { }

Now, import it in the module:

@NgModule({
declarations: [CustomButtonComponent]
})
export class AppModule { }

F. AngularJS $scope Missing in Angular

Angular doesn’t use $scope, which is why $scope-dependent code breaks.

Fix: Use BehaviorSubject Instead of $scope

Before (AngularJS Controller with $scope)

angular.module('app').controller('MainCtrl', function($scope) {
$scope.message = "Hello World";
});

After (Angular Component with BehaviorSubject)

import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Component({
selector: 'app-main',
template: '<p>{{ message$ | async }}</p>'
})
export class MainComponent {
message$ = new BehaviorSubject<string>('Hello World');
}
  • BehaviorSubject stores the state like $scope, and updates UI reactively.

4. Checking for Missing Dependencies

After fixing missing dependencies, run:

npm install
ng serve --open
  • If errors persist, check package.json for missing dependencies:
npm outdated
  • If a module is missing, manually add it:
npm install <missing-package>
  • If ng serve still fails, try:
npm rebuild

Leave a Reply

Your email address will not be published. Required fields are marked *