Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify providers at service in Angular 2

Tags:

angular

I'm trying to use Angular 2's DI system to automatically handle my services' dependencies. I'd like to use an annotation on the service itself, rather than using the second parameter of bootstrap() to specify all injectable services.

What I've Got

A low-level service:

services/role-store.ts

export class RoleStore {
  constructor() {
    // Initialize roles
  }

  getById( id ) {
    // accepts id, returns role object
  }
};

A high-level service that depends on the low-level service:

services/user-store.ts

import {Injectable} from 'angular2/angular2';
import {RoleStore} from './role-store.ts';

@Injectable()
export class UserStore {
  constructor( roleStore: RoleStore ) {
    this.roleStore = roleStore;
    // Initialize users
  }

  roleForUser( user ) {
    let role = this.roleStore.getById( user.roleId );
    return role;
  }
};

A component that depends on the high-level service:

components/user-dir.ts

import {Component, View, CORE_DIRECTIVES} from 'angular2/angular2';

import {UserStore} from '../services/user-store';

@Component({
  selector: 'user-dir',
  bindings: [UserStore]
})
@View({
  template: '<!-- inline template -->',
  directives: [CORE_DIRECTIVES]
})
export class UserDir {
  constructor( data: UserStore ) {
    this.userStore
  }
  // other methods...
}

A root component to bootstrap:

app.ts

import {Component, View, bootstrap} from 'angular2/angular2';

import {RoleStore} from './services/role-store';
import {UserDir} from './components/user-dir';

@Component({
  selector: 'app'
})
@View({
  template: '<user-dir></user-dir>',
  styleUrls: ['./app.css'],
  directives: [UserDir]
})
class App {}

bootstrap( App, [RoleStore] );

The Problem

bootstrap( App, [RoleStore] ) works, but I'd rather have an annotation in user-store.ts that tells Angular to inject RoleStore.

Something like @Provide( RoleStore ) class UserStore {}.

Any advice?

like image 260
Tyler Eich Avatar asked Oct 21 '15 19:10

Tyler Eich


People also ask

What is provider in Angular for service?

A provider is an object declared to Angular so that it can be injected in the constructor of your components, directives and other classes instantiated by Angular.

What are providers in Angular 2?

A provider is an instruction to the Dependency Injection system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide. For the final sample application using the provider that this page describes, see the live example / download example .

What is the difference between providedIn and providers in Angular?

What is the difference between providers:[ ] and providedIn? Essentially the same thing, just a difference in who tells the service where it should be injected.

What are providers in NgModule?

providers: Creators of services that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)


1 Answers

providers on services are not supported https://github.com/angular/angular/issues/5622

What you can do instead is creating arrays of providers that are exported like "modules"

export const ROLE_STORE_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
    [RoleStore];

and then in modules that use RoleStore service

export const PARENT_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
    [ParentService, RoleStore];

and then use it in bootstrap

bootstrap(AppComponent, [PARENT_PROVIDERS]);

I admit that is not what you asked for but the closest I found so far.

like image 105
Günter Zöchbauer Avatar answered Oct 01 '22 19:10

Günter Zöchbauer