I have a dynamic form items in component.
itemFormGroup = new FormGroup({
x: new FormControl(4),
y: new FormControl(1),
z: new FormControl(0),
});
itemsForm = new FormGroup({
items: new FormArray([
this.itemFormGroup
])
});
I want to bind this lines for input text.
<table class="table table-borderless" [formGroup]="itemsForm">
<thead>
<tr>
<th>x</th>
<th>y</th>
<th>z</th>
</tr>
</thead>
<tbody formArrayName="items">
<tr *ngFor="let item of items.controls; let i=index">
<td><input type="text" class="form-control form-control-sm" [formControlName]="item.x"></td>
<td><input type="text" class="form-control form-control-sm" [formControlName]="item.y"></td>
<td><input type="text" class="form-control form-control-sm" [formControlName]="item.z" disabled></td>
</tr>
</tbody>
</table>
But this shows error on browser "Failed to compile."
Error: src/app/app.component.html:40:43 - error TS2339: Property 'items' does not exist on type 'AppComponent'.
40 <tr *ngFor="let item of items.controls; let i=index">
Angular is looking for items
property in your component instance but can't find.
You can create a getter like:
get items() {
return this.itemsForm.get('items') as FormArray;
}
Then replace your ngFor
loop with the following:
<tr *ngFor="let item of items.controls; let i=index" [formGroupName]="i">
<td><input type="text" class="form-control form-control-sm" formControlName="x"></td>
<td><input type="text" class="form-control form-control-sm" formControlName="y"></td>
<td><input type="text" class="form-control form-control-sm" formControlName="z" [disabled]="true"></td>
</tr>
Note: I added [formGroupName]="i"
to narrow context for Angular form and replaced [formControlName]="item.x"
with string formControlName="x"
If you don't want to use typed version you can get rid of get items()
in component and just use:
*ngFor="let item of $any(itemsForm.get('items')).controls; let i=index"