This is the most upvoted error in Stackoverflow (https://stackoverflow.com/questions/38892771/cant-bind-to-ngmodel-since-it-isnt-a-known-property-of-input)
Angular has a very decent description of what are the reasons behind this error. In this article, we will dig a little bit further to understand and memorize the reasons in a way so we'll not google again (hopefully!).
Before start, let's have a quick look at what the document says
This error often means that you haven't declared the directive "x" or haven't imported the NgModule to which "x" belongs.
Perhaps you declared "x" in an application sub-module but forgot to export it. The "x" class isn't visible to other modules until you add it to the
exports
list.
So we'll get this error if we don't import the correct module or if we forgot to export some components.
Let's explore the use cases
1. Module is not properly imported
Let's add a module say ModuleA
and a component say ComponentA
alongside AppModule
Let's make this module empty
@NgModule({
declarations: [ComponentA],
imports: [],
providers: [],
exports: [ComponentA]
})
export class ModuleA { }
Now in the HTML
try to use ngFor
<h1 *ngFor="let foo of bar">{{foo}}</h1>
In the console, we'll see a warning
Can't bind to 'ngForOf' since it isn't a known property of 'h1'.
The problem is, it doesn't say which component, to find out we need to expand the warning and see ComponentA_Template
has this issue.
Also, the warning doesn't tell which module is missing, unfortunately, we need to find out this ourselves, in this case, it is required CommonModule
.
In a similar fashion, this can happen for ngModel
which required FormsModule
. Even it is applicable for our custom component for example if we forgot to import ModuleA
to AppModule
then it'll show a similar type of error.
Important to remember, sometimes you'll see this error to browser but most of the time this error is shown in the build
2. Wrong property binding in HTML
template
We know in general HTML
is case-insensitive, so if we bind a property wrongly it doesn't show any error for example
if you write <td colSpan="2">
instead <td colspan="2">
it'll render correctly but if we try to write something
<td colspan="{{1+1}}">
instead <td colSpan="{{1+1}}">
It'll show error
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
Important to remember in Angular most of the property binding is camelCase
like ngModel
, ngClass
and so on
3. Wrong Input/Output declaration
We know this is a very powerful communication medium but sometimes it can be troublesome. So when we are in this situation we need to look the annotation syntax @
or make sure it is present in the input/output
array.
If we declare Input() public foo: string;
instead @Input() public foo: string;
but this is hard to reproduce!
So how it can be missing from input/output
array
@Component({
selector: 'component-a',
templateUrl: './component-a.html',
styleUrls: [],
inputs: ['fooo'] // it can be misspell since it is string
})
In the template
<component-a foo="bar"></component-a>
Then we end up with an unpleasant error
Uncaught Error: Template parse errors:
Can't bind to 'item' since it isn't a known property of 'app-item-detail'
Important to remember, It is a best practice to use annotated @Input()/@Output()
declaration and avoid alias naming
Rule of thumb
- If the element is Angular
directive
then checkCommonModule
is in place - If the element is
Web Component
then checkCUSTOM_ELEMENTS_SCHEMA
is added to@NgModule.schemas
- If the element is added by you then make sure the respective module is imported and the component is in the export list.
- If we're using
@Input()/@Output()
follow the best practices, ie. always use the annotated declaration.
I hope you understand the reasons for this error and you'll avoid the trap. If you have any question please let me know in the comments. Happy coding
Top comments (0)