I am seeing strange behaviour with ngFor in combination with ngModel. Here's an example:
heroes = [
{
"name": "Deadpool"
},
{
"name": "Thor"
},
{
"name": "Superman"
},
{
"name": "Batman"
}
];
With the following code:
<div *ngFor="let hero of heroes;">
<div class="row">
<div class="input">
<label>Superhero</label>
<input [(ngModel)]="hero.name" name="hero">
</div>
</div>
</div>
Result:
Superhero: Batman
Superhero: Batman
Superhero: Batman
Superhero: Batman
Whereas if I don't use ngModel, but just print the value instead, it works correctly:
<div *ngFor="let hero of heroes;">
<div class="row">
<div class="input">
<label>Superhero</label>
<span>{{hero.name}}</span>
</div>
</div>
</div>
Result:
Superhero: Deadpool
Superhero: Thor
Superhero: Superman
Superhero: Batman
Can anyone tell me what I'm doing wrong?
The ngModel directive is a directive that is used to bind the values of the HTML controls (input, select, and textarea) or any custom form controls, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during form validations.
NgModel is used to create a top-level form group Instance, and it binds the form to the given form value. NgModule: Module used by NgModel is: FormsModule.
To fix Can't bind to 'ngModel' since it isn't a known property of 'input' error in Angular applications we have to import FormModule in app. module. ts file. If you are using FormBuilder class to create reactive form we have to import ReactiveFormsModule as well to avoid below error.
The two-way data binding.is the recommended way to set the value in the template-driven forms. The following code uses the [(ngModel)]="contact. firstname" to bind the firstname HTML element to the contact. firstname field in the component class.
Only issue here is input same input
name
:
change name="hero"
to name="hero{{i}}"
<div *ngFor="let hero of heroes;let i = index;">
<input [(ngModel)]="hero.name" name="hero{{i}}">
</div>
You are not doing much wrong. Let me show you how to fix, step by step:
1) Use single quotes ' and not double quotes " in your heroes array, it should be like this:
heroes = [
{
'name': 'Deadpool'
},
{
'name': 'Thor'
},
{
'name': 'Superman'
},
{
'name': 'Batman'
}
];
2) To just show the values in an input field you can use:
value="{{hero.name}}" OR [value]="hero.name" and same goes with name like this:
<input value="{{hero.name}}" name="{{hero.name}}">
<input [value]="hero.name" [name]="hero">
3) For using ngModel you need to have FormsModule in your imports array in app.module.ts and import import { FormsModule } from '@angular/forms'; like this:
import { FormsModule } from '@angular/forms';
imports: [
BrowserModule,
FormsModule
]
Now two way data binding would work:
<div *ngFor="let hero of heroes;">
<div class="row">
<div class="col-md-4">
<div class="input">
<label>Superhero</label>
// Just show value in input
<input value="{{hero.name}}" name="{{hero.name}}">
// Another way to Just show value in input
<input [value]="hero.name" [name]="hero.name">
// This is our boy who make two way data binding easy
<input [(ngModel)]="hero.name" [name]="hero.name">
<div></div>
</div>
</div>
</div>
</div>
Hope this helps. Thanks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With