Reputation: 4972
Based on the this stack overflow answer about generating formControlName
for each extracted index of an array, I did the following:
Suppose we have and array of indexes called odkDataIndexes
having lets say the following:
odkDataIndexes = ['id', 'name'];
So I need to generate 2 form controls with each having the correspondent names:
createIndexesForm(extractedIndexesArray): void {
this.indexesForm = this.fb.group({
mappingFieldItems: this.fb.array(
extractedIndexesArray.map(values => {
return this.fb.group(values);
})
)
});
}
And then on button click, I need to generate the form controls:
async generateMappingFields() {
this.showFields = false;
if (this.odkDataIndexes.length > 0) {
this.createIndexesForm(this.odkDataIndexes);
}
this.showFields = true;
}
At the HTML side I have the following:
<div *ngIf="showFields">
<mat-spinner *ngIf="!indexesForm" value="50" class="setSpinnerOnTop" diameter="75" [color]="medair-color"></mat-spinner>
<div [formGroup]="indexesForm" *ngIf="indexesForm">
<div formArrayName="mappingFieldItems">
<div *ngFor="let fg of indexesForm.get('mappingFieldItems').controls" [formGroup]="fg">
<ng-container *ngFor="let fc of fg.controls | keyvalue">
<!-- <input type="text" [formControl]="fc.value"> -->
<span></span>
<mat-form-field class="formFieldWidth" color="warn" appearance="fill">
<mat-label>{{fc.value | keyvalue}}</mat-label>
<mat-select [formControl]="fc.value">
<mat-option (click)="getName(fc.value, de.id, fg.controls)" *ngFor="let de of dataElementsDetails; let i = index;" [value]="de.id">
{{de.code}}
</mat-option>
</mat-select>
</mat-form-field>
</ng-container>
</div>
</div>
</div>
</div>
Now for each index inside the odkDataIndexes
, instead of showing only one drop down list per index, it is showing 7 or 8 depending on selected data.
The getName(fc.value, de.id, fg.controls)
is retuning the following on click:
And this image shows that for only one index, there is 16 drop down list, and the last consoled value of fg.ccontrols
contains 18 arrays.
I did a stackblitz with only the code in it.
Upvotes: 1
Views: 1134
Reputation: 24424
I don't think you need to use reactive form array just a formGroup can work for you by generate formGroup base of dataIndexes
value
component
createIndexesForm(extractedIndexesArray: string[]): void {
// ["id", "name"] 👉 {id:null,name:null}
const controls = extractedIndexesArray.reduce((g, k) => {
g[k] = null;
return g;
}, {});
this.indexesForm = this.fb.group({
mappingFieldItems: this.fb.group(controls)
});
}
template
<div [formGroup]="indexesForm" *ngIf="indexesForm">
<div [formGroup]="indexesForm.get('mappingFieldItems')">
<div *ngFor="let controlName of dataIndexes">
<mat-form-field class="formFieldWidth" color="warn" appearance="fill">
<mat-label>{{controlName}}</mat-label>
<mat-select [formControlName]="controlName">
<mat-option *ngFor="let de of dataElementsDetails; let i = index;"
[value]="de">
{{de}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
Upvotes: 1