Can't bind input when using abstract classes (2+ level of hierarchy)

Viewed 2830

In my Angular app:

  • When a Component uses an Input that is defined in its direct parent (abstract) class, everything works fine.

  • When a Component uses an Input that is defined in a 2-levels up parent (abstract) class, the ng build or ng serve give an error.

For example, I have 4 classes:

export abstract class AbstractAComponent {
  @Input() myInput: string;
}
export abstract class AbstractBComponent extends AbstractAComponent {}
@Component({
  selector: 'app-one',
  templateUrl: './one.component.html',
  styleUrls: ['./one.component.scss']
})
export class OneComponent extends AbstractAComponent {}
@Component({
  selector: 'app-two',
  templateUrl: './two.component.html',
  styleUrls: ['./two.component.scss']
})
export class TwoComponent extends AbstractBComponent {}

This is how I use them:

<app-one [myInput]="'value 1'"></app-one>
<app-two [myInput]="'value 2'"></app-two>

In a nutshell: - @Input() myInput is defined in AbstractAComponent - OneComponent directly extends AbstractAComponent - TwoComponent extends AbstractBComponent which extends AbstractAComponent

Expected behaviour: - both OneComponent and TwoComponent should have @Input() myInput

Current behaviour: - looks like TwoComponent doesn't correctly inherit @Input() myInput

and I got the following error:

ERROR in src/app/app.component.html:2:10 - error NG8002: Can't bind to 'myInput' since it isn't a known property of 'app-two'.
1. If 'app-two' is an Angular component and it has 'myInput' input, then verify that it is part of this module.
2. If 'app-two' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.
2 Answers

I initially thought that this was a bug and reported it here where I was actually pointed to the solution by elvisbegovic


The solution is to add @Directive() to your abstract class(es), my in example:

import { Directive, Input } from '@angular/core';

@Directive()
export abstract class AbstractAComponent {
  @Input() myInput: string;
}
import { Directive } from '@angular/core';

@Directive()
export abstract class AbstractBComponent extends AbstractAComponent {}

let try this one: In AbstractAComponent, added @Directive().

@Directive()
export abstract class AbstractAComponent {
   @Input() myInput: string;
}

And in OneComponent, added super(); in constructor. This work for me.

export class OneComponent extends AbstractAComponent {
   constructor() {
       super();
   }
}
Related