Issue
This is how I set my form control:
formMain = this.fb.group({
details: this.fb.array([
new FormGroup({
label: new FormControl(''),
description: new FormControl(''),
})
])
});
My HTML has some dynamic input fields:
<div formArrayName="details">
<div *ngFor="let detail of formMain.value.details; index as i">
<mat-form-field appearance="fill">
<mat-label>Label of a detail</mat-label>
<input id="detail-label" matInput type="text" [value]="detail.label">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Description of a detail</mat-label>
<input id="detail-description" matInput type="text" [value]="detail.description">
</mat-form-field>
</div>
</div>
This works fine. So if the form controls include values, they will be passed to the values of the input fields. I can edit these values, however, the new values will not be stored in the form control. This may be because I am not using formControlName
.
This is how I added formControlName
and also [formGroupName]="i"
:
<div *ngFor="let detail of formMain.value.details; index as i" [formGroupName]="i">
<mat-form-field appearance="fill">
<mat-label>Label of a detail</mat-label>
<input id="detail-label" matInput type="text" [value]="detail.label" formControlName="label">
</mat-form-field>
...
I receive no errors but I am no longer able to edit the values of the input fields. Neither I can't focus the input field with the mouse or even mark the values. The input fields are completely locked. This is what I see in the DOM:
<div class="mat-form-field-infix ng-tns-c97-1030"><input _ngcontent-lqv-c198="" id="detail-label" matinput="" type="text" formcontrolname="label" class="mat-input-element mat-form-field-autofill-control ng-tns-c97-1030 ng-untouched ng-pristine ng-valid cdk-text-field-autofill-monitored" ng-reflect-name="label" ng-reflect-id="detail-label" ng-reflect-type="text" ng-reflect-value="Brooklyn" aria-invalid="false" aria-required="false"><span class="mat-form-field-label-wrapper ng-tns-c97-1030"><label class="mat-form-field-label ng-tns-c97-1030 ng-star-inserted" ng-reflect-disabled="true" id="mat-form-field-label-2045" ng-reflect-ng-switch="true" for="detail-label" aria-owns="detail-label"><!--bindings={
"ng-reflect-ng-switch-case": "false"
}--><mat-label _ngcontent-lqv-c198="" class="ng-tns-c97-1030 ng-star-inserted">Label of a detail</mat-label><!--bindings={
"ng-reflect-ng-switch-case": "true"
}--><!--bindings={
"ng-reflect-ng-if": "false"
}--></label><!--bindings={
"ng-reflect-ng-if": "true"
}--></span></div>
This happens because of [formGroupName]="i"
. If I remove that, I can edit the values of the input field but then I receive the error:
ERROR Error: Cannot find control with path: 'details -> label'
How do I fix this?
Solution
You should loop the form controls of the details
FormArray
instead of the objects in the details array in the *ngFor
.
And you don't need to supply the [value]
attribute as when applying the formControlName
attribute, the input field will be bound with value.
<div
*ngFor="let detail of detailsFormArray.controls; index as i"
[formGroupName]="i"
>
<mat-form-field appearance="fill">
<mat-label>Label of a detail</mat-label>
<input id="detail-label" matInput type="text" formControlName="label" />
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Description of a detail</mat-label>
<input
id="detail-description"
matInput
type="text"
formControlName="description"
/>
</mat-form-field>
</div>
get detailsFormArray() {
return this.formMain.controls.details as FormArray;
}
Reference: Angular FormArray: Complete Guide
Answered By - Yong Shun
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.