1

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

G.D.
  • 75
  • 9

2 Answers2

1

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.

G.D.
  • 75
  • 9
0

Do you need to use a constructor and custom injection token?

I got it working here using ngOnInit along with getters and setters https://stackblitz.com/edit/angular-ivy-9a7tfx?file=src/app/authors.service.ts

Kevin
  • 199
  • 5
  • 20
  • Thanks for your proposal, but this is not really wat I want to achieve. At the end I really just would like to have a component to be used like `` or ``. I Know there are other options to do that but I would like to understand if there is a possible solution for this particular scenario – G.D. Mar 04 '22 at 07:16
  • yeah I was playing around more with making the injection token factory more dynamic - let me keep playing with it – Kevin Mar 05 '22 at 02:09
  • [link](https://stackblitz.com/edit/angular-ivy-uuybm2?file=src/app/authors-complex-component/specific-complex-authors-components/authors-complex-international.component.ts) I just edit a new version with token injection in a service where there are also other automatic injection like HttpClient, because that was my second problem in this case @Kevin – G.D. Mar 05 '22 at 10:57
  • just updated answer with a possible solution easy and clean – G.D. Aug 18 '22 at 16:20