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

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

4 Comments

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 <app-authors [type]="international"></app-authors> or <app-authors [type]="local"></app-authors>. 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
yeah I was playing around more with making the injection token factory more dynamic - let me keep playing with it
link 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
just updated answer with a possible solution easy and clean

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.