Reputation: 4163
Within Angular I have child component which inherits from a parent component. This parent component injects multiple classes. I want to extend the child component with an injection class which I do not use in the parent class. Before this extension it was not required to instantiate the constructor and call super( *args* )
. When I try to extend the constructor though, I get the following error message:
Constructors for derived classes must contain a 'super' call
Is there a way not to be required to call the super class while extending the class with an injection? Let me know if something is not clear about this question.
Parent component
@Component({ template: '' })
export abstract class ParentComponent<T> implements OnInit, OnDestroy {
constructor(
protected formBuilder: FormBuilder,
protected route: ActivatedRoute,
protected snackBar: MatSnackBar,
protected location: Location
) {
const routeParams = this.route.snapshot.params;
if (routeParams && routeParams.id) {
this.subjectId = this.route.snapshot.params.id;
}
}
}
Child component
export class ChildComponent extends ParentComponent<MyT> {
constructor(
/** I want to extend with the following service */
protected myService: Service
) {
// But as I instantiate this constructor, I also need to call super() with the required params
}
}
Question extension
To extend my question; I am not sure if this double importing of the super class parameters and passing it is overhead. The main reason for this question is because I try to keep the code as clean as possible and try to overcome duplicate code. Duplicate importation of the injection classes for the sake of providing it in the super
call feels a bit useless.
Upvotes: 3
Views: 2904
Reputation: 4707
After reading your question a few times, I'm not sure that this is understood so I will post it as an answer.
You can extend your parent class and add a service, but you still need to call the parent's constructor. This is unavoidable. You don't need to re-inject anything, although you still need to declare them, at least.
Your child's constructor should look like this:
constructor(
formBuilder: FormBuilder,
route: ActivatedRoute,
snackBar: MatSnackBar,
location: Location,
protected myService: Service // note the "protected" here but not above
) {
super(formBuilder, route, snackBar, location);
}
The non-protected
arguments of the child constructor are essentially "pass-throughs", so to speak, to your parent's declarations of what should be injected. There is nothing being double-injected or anything like that.
Upvotes: 1
Reputation: 12196
I suppose you are afraid of injecting all the things to you parent. That is why you need that behavior. I'm afraid there is no such option with angular DI. The best thing you can do is common style for all components to inject Injector
instead of its dependencies and then getting all the dependencies through injector.
class Parent {
private myService = this.injector.get(MyService)
private myService2 = this.injector.get(MyService2)
constructor(@Inject(INJECTOR) injector: Injector){}
}
class Child extends Parent {
constructor(@Inject(INJECTOR) injector: Injector) {
super(injector);
}
}
if Parent is not a component in all of this cases you can omit @Inject(INJECTOR)
in its constructor
Upvotes: 2