Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject a service requiring constructor parameter

I have a service that requires some value to be initiated:

@Injectable() export class MyService {   private myVals: any;    constructor(init : any) {     this.myVals = init;   } } 

And the consumer:

@Component(...) export class MyComponent {   private svc: MyService;   constructor(private svc : MyService) {   } } 

So is there a way to inject and pass the required parameter to MyService's constructor "during" dependency injection??

Something like:

constructor(private svc({ // init vales }) : MyService) {} 

I know I can pass by variable, but interested to find if there's a way to do this from the API.

like image 206
gt6707a Avatar asked Nov 12 '16 01:11

gt6707a


People also ask

Why do we inject service in constructor?

When Angular creates a HeroesComponent, the Dependency Injection system sets the heroService parameter to the singleton instance of HeroService. You can tell Angular to inject a dependency in the component's constructor by specifying a constructor parameter with the dependency type.

What is @inject in constructor?

Constructor Injection is the most common form of Dependency Injection. Constructor Injection is the act of statically defining the list of required dependencies by specifying them as parameters to the class's constructor.

Why we inject services in constructor in Angular?

Angular provides the ability for you to inject a service into a component to give that component access to the service. The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency.

Can a service have a constructor Angular?

Also, DI in our Angular components/services can be implemented using either constructor or injector.


2 Answers

There is an official way that Angular team recommends in here. It basically allows you to inject statically typed configuration classes.

I have successfully implemented it and here is all the relevant code:

1) app.config.ts

import { OpaqueToken } from "@angular/core";  export let APP_CONFIG = new OpaqueToken("app.config");  export interface IAppConfig {     apiEndpoint: string; }  export const AppConfig: IAppConfig = {         apiEndpoint: "http://localhost:15422/api/"     }; 

2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';  @NgModule({     providers: [         { provide: APP_CONFIG, useValue: AppConfig }     ] }) 

3) your.service.ts

import { APP_CONFIG, IAppConfig } from './app.config';  @Injectable() export class YourService {      constructor(@Inject(APP_CONFIG) private config: IAppConfig) {              // You can use config.apiEndpoint now     }    } 

Now you can inject the config everywhere without using the string names and with the use of your interface for static checks.

You can of course separate the Interface and the constant further to be able to supply different values in production and development e.g.

like image 175
Ilya Chernomordik Avatar answered Oct 10 '22 04:10

Ilya Chernomordik


The above answer has been deprecated since angular 4 Now you can use it like this:

import { NgModule, APP_INITIALIZER } from '@angular/core';  @NgModule({   providers: [     {       provide: APP_INITIALIZER,       useFactory: onAppInit1,       multi: true,       deps: [/* your dependencies */]     },     {       provide: APP_INITIALIZER,       useFactory: onAppInit2,       multi: true,       deps: [/* your dependencies */]     }   ] }) export class AppModule { } 
like image 22
Black Mamba Avatar answered Oct 10 '22 04:10

Black Mamba