downgradeInjectable

Experimental Function

What it does

Part of the upgrade/static library for hybrid upgrade apps that support AoT compilation

Allow an Angular 2+ service to be accessible from Angular 1.

How to use

First ensure that the service to be downgraded is provided in an NgModule that will be part of the upgrade application. For example, let's assume we have defined HeroesService

// This Angular 2 service will be "downgraded" to be used in Angular 1
@Injectable()
class HeroesService {
  heroes: Hero[] = [
    {name: 'superman', description: 'The man of steel'},
    {name: 'wonder woman', description: 'Princess of the Amazons'},
    {name: 'thor', description: 'The hammer-wielding god'}
  ];

  constructor(@Inject('titleCase') titleCase: (v: string) => string) {
    // Change all the hero names to title case, using the "upgraded" Angular 1 service
    this.heroes.forEach((hero: Hero) => hero.name = titleCase(hero.name));
  }

  addHero() {
    this.heroes =
        this.heroes.concat([{name: 'Kamala Khan', description: 'Epic shape-shifting healer'}]);
  }

  removeHero(hero: Hero) { this.heroes = this.heroes.filter((item: Hero) => item !== hero); }
}

and that we have included this in our upgrade app NgModule

// This NgModule represents the Angular 2 pieces of the application
@NgModule({
  declarations: [Ng2HeroesComponent, Ng1HeroComponentWrapper],
  providers: [
    HeroesService,
    // Register an Angular 2+ provider whose value is the "upgraded" Angular 1 service
    {provide: 'titleCase', useFactory: (i: any) => i.get('titleCase'), deps: ['$injector']}
  ],
  // All components that are to be "downgraded" must be declared as `entryComponents`
  entryComponents: [Ng2HeroesComponent],
  // We must import `UpgradeModule` to get access to the Angular 1 core services
  imports: [BrowserModule, UpgradeModule]
})
class Ng2AppModule {
  ngDoBootstrap() { /* this is a placeholder to stop the boostrapper from complaining */
  }
}

Now we can register the downgradeInjectable factory function for the service on an Angular 1 module.

// Register an Angular 1 service, whose value is the "downgraded" Angular 2+ injectable.
ng1AppModule.factory('heroesService', downgradeInjectable(HeroesService));

Inside an Angular 1 component's controller we can get hold of the downgraded service via the name we gave when downgrading.

// This is our top level application component
ng1AppModule.component('exampleApp', {
  // We inject the "downgraded" HeroesService into this Angular 1 component
  // (We don't need the `HeroesService` type for Angular 1 DI - it just helps with TypeScript
  // compilation)
  controller: [
    'heroesService', function(heroesService: HeroesService) { this.heroesService = heroesService; }
  ],
  // This template make use of the downgraded `ng2-heroes` component
  // Note that because its element is compiled by Angular 1 we must use kebab-case attributes for
  // inputs and outputs
  template: `<link rel="stylesheet" href="./styles.css">
             <ng2-heroes [heroes]="$ctrl.heroesService.heroes" (add-hero)="$ctrl.heroesService.addHero()" (remove-hero)="$ctrl.heroesService.removeHero($event)">
               There are {{ $ctrl.heroesService.heroes.length }} heroes.
             </ng2-heroes>`
});

Class Export

export downgradeInjectable(token: any)

Takes a token that identifies a service provided from Angular 2+.

Returns a factory function that can be used to register the service on an Angular 1 module.

The factory function provides access to the Angular 2+ service that is identified by the token parameter.

exported from @angular/upgrade/static defined in @angular/upgrade/src/aot/downgrade_injectable.ts

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://v2.angular.io/docs/ts/latest/api/upgrade/static/downgradeInjectable-function.html