Search code examples
angularangular-servicesangular-injector

Angular Service inject parameter in constructor based on component @Input property


I have a Service with a parameter in the constructor here a simple string later on a url or other objects. This parameter is a set for the internal behaviour of the service, here just instantiate different values.


  constructor(@Inject(AUTHOR_TYPE) public authType: string ) { 

    console.log('Auth type is ' + authType);
    
    if(authType == 'international')
      this.authors = ["a1","a2","a2","a3"];
    else
      this.authors = ["local1","local2","local2","local3"];
  }

This service is used inside a component. this component has an input parameter to make component flexible and reusable.

export class AuthorsComponent implements OnInit {

  @Input('type')
  type: 'local' | 'international' = "local";
  authors: string[];
  
  constructor(service: AuthorsService) {
    this.authors = service.getAuthors();
   }

  ngOnInit(): void {

    console.log('component init as ' + this.type);
  }
}

I would like to have a component capable to switch between different types using an input parameter (or other binding mode) and based on the component type be able to set the internal service to change behaviour.

In live example below I just have a component Authors with a custom parameter and inside the service to retrieve a list of authors, there is a way to achieve this?

Live example


[UPDATE]

A possible solution using @Inject on service and actually using 2 component with 2 predefined InjectionTocken. Still doesn't seems the optimal solution, since I have a general Component more or less empty, just groping and display sub components + 2 specified component. Reached the scope but I have generated too many component. Still open to other solutions. Thanks

possible solution


Solution

  • If somebody is interested in one possible solution, I figured it out a nice and easy solution:

    selector.component that expose one input property [mode] of type enumeration

    import { Component, OnInit, Input } from '@angular/core';
    
    @Component({
      selector: 'app-selector',
      template: `<div > {{ mode }}</div>`,
      styleUrls: ['./selector.component.scss']
    })
    export class SelectorComponent implements OnInit {
    
      @Input('mode') mode : ModeEn = ModeEn.first;
    
      constructor() { }
    
      ngOnInit(): void {
      }
    
    }
    
    export enum ModeEn{
      first = 'first',
      second = 'second'
    }
    

    can be used from other component easily just importing the enumeration and assign a new property to it

    import { ModeEn } from './selector/selector.component';
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      template: `
      <app-selector [mode]="mode.first"></app-selector>
      <app-selector [mode]="mode.second"></app-selector>`,
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
    
      mode = ModeEn;
    }
    

    in this way the app-selector component expose all possible mode and where is used an import will simplify and restrict possible mode only to available one.