I have abstract class(without constructor) and I want to inject another class into it.
Abstract class:
import { ErrorHandler } from '../../shared/services/errorHandler.service';
import { Inject } from '@angular/core';
export abstract class BaseApiComponent<T> {
@Inject(ErrorHandler) errorHandler: ErrorHandler;
this.errorHandler.test();
}
Injected class:
import { Injectable } from '@angular/core';
@Injectable()
export class ErrorHandler {
constructor() { }
public test() {
console.log('Test');
}
}
And I have next error
ORIGINAL EXCEPTION: TypeError: Cannot read property 'test' of undefined
How i can fix this?
As of Angular 2 RC5 the DI becomes simpler. You don't need to decorate the stuff with @Injectable()
. Instead, you just declare it for DI in one place - NgModule.
export class ErrorHandler {
test() {
console.log('ErrorHandler.test()');
}
}
export abstract class BaseApiComponent<T> {
// use protected property parameter in abstract class
// for accessibility from descendants.
constructor(protected errorHandler: ErrorHandler) {}
someMethod() {
this.errorHandler.test();
}
}
export class ApiComponentImpl<T> extends BaseApiComponent<T> {
// use @Inject decorator
constructor(@Inject(ErrorHandler) errorHandler: ErrorHandler) {
super(errorHandler);
}
}
app.module.ts:
// class declarations
@NgModule({
providers: [
ErrorHandler,
ApiComponentImpl
]
})
export class AppModule{
}
// bootstrap the app
platformBrowserDynamic().bootstrapModule(AppModule);
You can employ OpaqueToken to improve modularity and remove type dependency:
export const errorHandlerToken = new OpaqueToken('ErrorHandler');
in the module:
providers: [
// using OpaqueTokens you can change the provided value
// to anything without changing consumer code
{provide: errorHandlerToken, useClass: ErrorHandler},
constructor:
constructor(@Inject(errorHandlerToken) errorHandler: ErrorHandler) {