Downgrade Angular 2 providers to Angular 1 services with downgradeInjectable
If you have followed the steps in Connecting Angular 1 and Angular 2 with UpgradeModule, you should now have a hybrid application that is capable of sharing different elements with the opposing framework. If you are unfamiliar with Angular 2 providers, it is recommended that you go through the dependency injection chapter before you proceed.
Like with templated components, interchangeability is also offered to service types. It is possible to define a service type in Angular 2 and then inject it into an Angular 1 context.
Note
The code, links, and a live example in relation to this recipe are available at http://ngcookbook.herokuapp.com/2824/.
Getting ready
Begin with the code written in Connecting Angular 1 and Angular 2 with UpgradeModule.
How to do it...
First, define the service you would like to inject into an Angular 1 component:
[app/article.service.ts]
import {Injectable} from '@angular/core';
@Injectable()
export class ArticleService {
article:Object = {
title: 'Research Shows Moon Not Actually Made of Cheese',
author: 'Jake Hsu'
};
}
Next, define the Angular 1 component that should inject it:
[app/article.component.ts]
export const ng1Article = {
template: `
<h1>{{article.title}}</h1>
<p>{{article.author}}</p>
`,
controller: (ArticleService, $scope) => {
$scope.article = ArticleService.article;
}
};
ArticleService won't be injected yet though, since Angular 1 has no idea that this service exists. Doing this is very simple, however. First, you'll list the service provider in the Angular 2 module definition as you normally would:
[app/ng2.module.ts]
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {UpgradeModule} from '@angular/upgrade/static';
import {RootComponent} from './root.component';
import {ArticleService} from './article.service';
@NgModule({
imports: [
BrowserModule,
UpgradeModule,
],
declarations: [
RootComponent
],
providers: [
ArticleService
],
bootstrap: [
RootComponent
]
})
export class Ng2AppModule {
constructor(public upgrade: UpgradeModule){}
}
Still, Angular 1 does not understand how to use the service.
In the same way you convert an Angular 2 component definition into an Angular 1 directive, convert an Angular 2 service into an Angular 1 factory. Use downgradeInjectable and add the Angular 1 component and the converted service to the Angular 1 module definition:
[app/ng1.module.ts] import 'angular'; import {ng1Article} from './article.component'; import {ArticleService} from './article.service'; import {downgradeInjectable} from '@angular/upgrade/static'; export const Ng1AppModule = angular.module('Ng1AppModule', []) .component('ng1Article', ng1Article) .factory('ArticleService', downgradeInjectable(ArticleService));
That's all! You should be able to see the Angular 1 component render with the data passed from the Angular 2 service.
See also
- Connecting Angular 1 and Angular 2 with UpgradeModule shows you how to run Angular 1 and 2 frameworks together
- Downgrading Angular 2 components to Angular 1 directives with downgradeComponent demonstrates how to use an Angular 2 component inside an Angular 1 application