17

Can I do this:

export class BaseComponent {
protected config: IConfig;

@Inject(AppConfig) protected appConfig: AppConfig;

constructor() 
{ 
    this.config = this.appConfig.getConfig();    
}

instead of this:

export class BaseComponent {
config: IConfig;

constructor(
    private appConfig: AppConfig,
    ) 
{ 
    this.config = appConfig.getConfig();    
}

The goal is to simplify the constructor signature, so all child component to not need to specify appConfig in their constructor. So the components that inherits from BaseComponent to look like this:

@Component({
    selector: 'sport-templates',
    templateUrl: 'templates.component.html',
    styleUrls: [ 'templates.component.scss' ],
    encapsulation: ViewEncapsulation.None
})
export class SportTemplates extends BaseComponent implements OnInit {

    constructor() {
        super();
    }

instead like this:

@Component({
    selector: 'sport-templates',
    templateUrl: 'templates.component.html',
    styleUrls: [ 'templates.component.scss' ],
    encapsulation: ViewEncapsulation.None
})
export class SportTemplates extends BaseComponent implements OnInit {

    constructor(appConfig: AppConfig) {
        super(appConfig);
     }
Nikola Yankov
  • 1,264
  • 1
  • 15
  • 28

3 Answers3

2

You can do this:

myService: MyService = this.injector.get(MyService);
constructor(private injector:Injector) {}

The Injector is in @angular/core

  • 1
    While it works, it doesn't look like the true way. More like a Service Locator pattern. Though I have to admit that difference is subtle. – XOR Mar 24 '17 at 14:08
1

This is now (since Angular v14) possible to do via the inject function from @angular/core. It behaves the same as the decorator and can be used on property initializers:

@Directive()
export abstract class BaseComponent {
    protected appConfig = inject(AppConfig)
}

Therefore, you don't need to call super(appConfig) any more.

kvetis
  • 6,682
  • 1
  • 28
  • 48
0

No you can't do it. Injectable service will e injected when the constructor is called.

The goal is to simplify the constructor signature.

There is no need to simplify constructor signature. For readability you can write them in multiple lines.

so all child component to not need to specify appConfig in their constructor

In your case only classes that inherit your class will access that. But if you mean child component those ones which are used in your component, they can't access variables in parent component. You need to pass them.

UPDATED

Your this.config is always visible in inherited components. There is no need to again inject appConfig in the SportTemplates component.

Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • Thank you for the reply. I added a bit clarification in my question. – Nikola Yankov Feb 13 '17 at 10:51
  • Now I have a BaseComponent which is inhereted by 19 child components. BaseComponent needs a service, to define a method which will get inhereted. Now I need to "send this service via" constructors of all 19 children. I guess that's what he meant with 'so all child components not need to specify "..." in their constructors' – Vladi Pavelka Jul 19 '19 at 12:01
  • If you have inheritance, you need to provide from child constructors to the parent constructor via `super()` call. – Suren Srapyan Jul 19 '19 at 12:05
  • 1
    @SurenSrapyan of course, therefore the 'Property injection instead of constructor injection' question, so that I don't have to. – Vladi Pavelka Jul 19 '19 at 12:14