POV
POV

Reputation: 12025

How to inject service in child classes Angular?

I have a custom concrete class in Angular that extends abstract class:

abstract class Tab<T> {
   constructor(protected parameters: T, protected _activeIndexTab?: number) {}
}

export class TabDictionary extends Tab<ITabDictioaryParameters> {
  constructor(parameters?: ITabDictioaryParameters) {

}

Concrete class I use like:

this.tabService.register(new TabDictionary()).build();

Problem is that to use DI of Route in class TabDictionary, I need to add dependency to parent abstract class, that does redundant dependencies.

How it can be simplified?

if my question is not clear enough, let me know

I want to have abstract class Tab<T> {} with all needed dependencies, which should be available in children classes

Upvotes: 0

Views: 907

Answers (1)

Chakradhar Vyza
Chakradhar Vyza

Reputation: 285

Use a class to store the injector This class will hold the module’s injector. It will be set once and retrieved whenever a component or service needs to get a service dependency.

app-injector.service.ts

import { Injector } from '@angular/core';

export class AppInjector {

private static injector: Injector;

static setInjector(injector: Injector) {

        AppInjector.injector = injector;

    }

static getInjector(): Injector {

return AppInjector.injector;

    }

}       

After the module has been bootstrapped, store the module’s injector in the AppInjector class.

main.ts

platformBrowserDynamic().bootstrapModule(AppModule).then((moduleRef) => {
    AppInjector.setInjector(moduleRef.injector);
});        

Use this injector class to assign dependencies Now, we can modify the base component to remove all constructor arguments.

base.component.ts

@Component({
    template: ''
})    
export class BaseComponent {    
    protected utilitiesService: UtilitiesService;    
    protected loggingService: LoggingService;

constructor() {    
        // Manually retrieve the dependencies from the injector    
        // so that constructor has no dependencies that must be passed in from child    
        const injector = AppInjector.getInjector();    
        this.utilitiesService = injector.get(UtilitiesService);    
        this.loggingService = injector.get(LoggingService);    
        this.logNavigation();

    }

    protected logError(errorMessage: string) { . . . }    
    private logNavigation() { . . . }
}         

Inherit child component from base component Now the child component only needs to use dependency injection for its own dependencies.

child.component.ts

@Component({ . . . })
export class ChildComponent extends BaseComponent {

constructor(private childDataService: ChildDataService) {    
    super();    
  }    
}            

Reference : https://devblogs.microsoft.com/premier-developer/angular-how-to-simplify-components-with-typescript-inheritance/

Upvotes: 1

Related Questions