Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally inject service into component?

I have 2 services one.service.ts and two.service.ts, and a component dashboard.component.ts.

How to conditionally inject those service into the component?

import { Component, ViewEncapsulation, Inject } from '@angular/core';
import { OneService } from '../services/one.service';
import { TwoService } from '../services/two.service';

@Component({
  selector: 'dashboard',
  encapsulation: ViewEncapsulation.Emulated,
  styleUrls: ['./dashboard.less'],
  templateUrl: './dashboard.html'
})
export class DashboardComponent {
    constructor() {
       // Here how do I get service instance based on some this condition.
         if(true) {
             /* Service **one.service.ts** to be injected */
         } else {
             /* Service **two.service.ts** to be injected */    
         }

    }
}
like image 210
Ajey Avatar asked Apr 17 '17 11:04

Ajey


People also ask

Which will inject services into component class?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.

What is the injectable () decorator used for?

Injectable() decorator is used to inject other services or objects into your service. If your service do not have any dependencies then you don't need to add Injectable() decorator.

What is angular injector?

Injectors are data structures that store instructions detailing where and how services form. They act as intermediaries within the Angular DI system. Module, directive, and component classes contain metadata specific to injectors. A new injector instance accompanies every one of these classes.


1 Answers

You can use the Injector

import { Injector } from '@angular/core'  
...
constructor(private injector: Injector){ 

  if(true) {
    this.oneService = <OneService>this.injector.get(OneService);
  } else {
    this.twoService = <TwoService>this.injector.get(TwoService);
  }
}

As @MeirionHughes mentioned this is called the service locator pattern:

The technique is an example of the service locator pattern.

Avoid this technique unless you genuinely need it. It encourages a careless grab-bag approach such as you see here. It's difficult to explain, understand, and test. You can't know by inspecting the constructor what this class requires or what it will do. It could acquire services from any ancestor component, not just its own. You're forced to spelunk the implementation to discover what it does.

Framework developers may take this approach when they must acquire services generically and dynamically.

Source: https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#explicit-injector

And again as mentioned you can get these injectors in another service and then inject this service into your component.

like image 145
eko Avatar answered Sep 21 '22 01:09

eko