The migration from Angular 10 to Angular 15 has caused the following error on the console:
ERROR Error: Cannot find control with path: 'mappedHeaders -> 0 -> value'
example.ts
headerArray: FormArray;
formGroup: FormGroup;
constructor(private fb: FormBuilder) {
this.headerArray = this.fb.array([]);
this.formGroup = this.fb.group({
mappedHeaders: this.headerArray
});
}
printing the structure of this.headerArray on the console post initilization:
printing the structure of this.formGroup on the console after pushing the values:
example.html:
<div [formGroup]="formGroup">
<table>
<tbody formArrayName="mappedHeaders">
<ng-container *ngFor="let header of accountHeaders; index as i">
<tr>
<td>{{i}}</td>
<td [formGroupName]="i">
<select class="ui fluid clearable selection search dropdown column-mapping-dropdown" formControlName="value">
<option *ngFor="let header of fileHeaders" [value]="header">{{ header }}</option>
</select>
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
the accountHeaders
is an array of strings like ['one', 'two', 'three',...'etc']
The above code works perfectly as expected in Angular 10. I have checked other similar issues but none could address this.
Update The controls are pushed into array post a network call:
const mapped = result['mappedHeaders'];
for (const accountHeader of this.accountHeaders.sort()) {
this.headerArray.push(this.fb.control({
key: accountHeader,
value: mapped[accountHeader]
}));
}
mapped
is a map of key value like ['one': 'one', 'two': 'three']
combining the answers given by @Naren and @Eliseo, the below modification to the code resolved the issue.
1 - The iteration must happen on the formArray controls:
get formArrayControls() {
const formArray = this.formGroup.get('mappedHeaders') as FormArray;
return formArray.controls;
}
and
<ng-container *ngFor="let header of formArrayControls; index as i">
2 - I was pushing formControls into mappedHeaders array instead of formGroups. Therefore, I created a method that adds the elements to the array:
addToFormArray(key: string, value: string) {
let formArray = this.formGroup.get('mappedHeaders') as FormArray;
formArray.push(this.fb.group({
key: [key],
value: [value]
}));
}
and call the function as follows:
for (const accountHeader of this.accountHeaders.sort()) {
this.addToFormArray(accountHeader, mapped[accountHeader]);
}