Ali Eshghi
Ali Eshghi

Reputation: 1243

Can't bind to 'Property X' since it isn't a known property of 'Child Component'

In my project I have a generic class and some other components which inherited from that.

BaseRdnInput.ts:

   @Injectable()
    export abstract class BaseRdnInput implements ControlValueAccessor, Validator {
    
      @Input() rdnModel?: any | Array<any>;
      @Output() rdnModelChange: EventEmitter<any | Array<any>> = new EventEmitter<any | Array<any>>();
      // many code after...
    }

RdnInputComponent.ts:

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'rdn-input',
  templateUrl: './rdn-input.component.html'
})
export class RdnInputComponent extends BaseRdnInput implements OnInit, AfterViewInit {
 // many code after...
constructor(public changeDetectorRef: ChangeDetectorRef) {
    super(changeDetectorRef);
  };
// many code after
}

Then I am using this component in ContractComponent.html:

<rdn-input [(rdnModel)]='headerEntity.saleNo'></rdn-input>

By this line of code I get this error :

Can't bind to 'rdnModel' since it isn't a known property of 'rdn-input'.

  1. If 'rdn-input' is an Angular component and it has 'rdnModel' input, then verify that it is part of this module.
  2. If 'rdn-input' 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.

It was working fine before I upgrading. My question is very similar to this one: Angular2 RC5: Can't bind to 'Property X' since it isn't a known property of 'Child Component'. I got that there are some setps to avoid this error and the most important is: checking if we add @input to the property of sub class or adding attr to the biding property of parent. if you see I have already added @input in BaseRdnInput.ts:. and I don't want to use attr because it will stop that property from being passed down to nested directives. Is there anyway to pass this?

Upvotes: 3

Views: 2510

Answers (2)

ABabin
ABabin

Reputation: 2947

I'm the one who wrote the accepted answer on the question you linked. Haven't worked with Angular in a looong time so bear with me, but I did some troubleshooting and possibly figured it out.

It's definitely an inheritance thing. I found this answer to a relevant question:

If a class inherits from a parent class and does not declare a constructor, it inherits the parent class constructor, and with it the parameter metadata of that parent class.

Because RdnInputComponent defines its own constructor, it's not inheriting the decorator metadata of the base class. If you remove the constructor, it then complains that BaseRdnInput doesn't have its own decorator and suggests, as did @Yngve B-Nilsen, adding @Directive(). That appears to fix the issue whether RdnInputComponent has a constructor or not (see this stackblitz).

Alternatively, just adding the inherited binded properties to inputs and outputs of the RdnInputComponent metadata seems to work as well (stackblitz), like so:

@Component({
  selector: 'rdn-input',
  templateUrl: './rdn-input.component.html',
  inputs: ['rdnModel'],
  outputs: ['rdnModelChange']
})
export class RdnInputComponent extends BaseRdnInput {
// ...

Hope that helps!

Upvotes: 2

Yngve B-Nilsen
Yngve B-Nilsen

Reputation: 9676

You need to decorate your base class with @Directive() - not @Injectable

Upvotes: 0

Related Questions