I have a dynamic array that has an onChange method on the select option. When I select the option the method works but when I add a new array and select the new option the first array resets. Here is my array:
<ng-container formGroupName="envelopeRequest">
<button (click)='initDocument()'>Add Document</button>
<ng-container formArrayName="documents">
<ng-container
*ngFor="let control of documents.controls; let comIndex=index"
>
<ng-container [formGroupName]="comIndex">
<div class="row justify-content-start mb-3">
<div class="col-md-1">
{{comIndex}}
<input
type="hidden"
id="fname"
name="fname"
formControlName="documentId"
/>
<label for="formFile" class="col-form-label">File:</label>
</div>
<div class="col-md-6">
<input
class="form-control"
type="file"
id="file"
name="file"
formControlName="name"
/>
</div>
</div>
<ng-container formArrayName="documentFields">
<ng-container
*ngFor="let skillIndex of documentFieldsIndexes(comIndex);"
>
<div class="row mb-3">
<label class="col-sm-1 col-form-label">Category:</label>
<div class="col-md-2">
<ng-container [formGroupName]="skillIndex">
<select id="" class="form-select" formControlName="value" (change)="changeCategoryList($event)">
<option selected>Select</option>
<option *ngFor="let c of categoryList">
{{c.name}}
</option>
</select>
</ng-container>
</div>
<label class="col-auto col-form-label">Sub-Category:</label>
<div class="col-md-2">
<ng-container [formGroupName]="skillIndex + 1">
<select id="" class="form-select" formControlName="value" (change)="changeSubCategoryList($event)">
<option selected>Select</option>
<option *ngFor="let s of subCategoryList">{{s.name}}</option>
</select>
</ng-container>
</div>
<label class="col-auto col-form-label">List:</label>
<div class="col-md-2">
<ng-container [formGroupName]="skillIndex + 2">
<select id="" class="form-select" formControlName="value">
<option selected>Select</option>
<option *ngFor="let name of typeList">{{name}}</option>
</select>
</ng-container>
</div>
</div>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
I'm assuming it's because both select options are using the same method now. Here is a snippet of my ts code:
changeCategoryList(category: any) {
this.subCategoryList = this.categoryList.find(
(cat: any) => cat.name == category.target.value
).subCategoryList;
}
changeSubCategoryList(subList: any) {
this.typeList = this.categoryList
.find((cat: any) => cat.name == this.selectedCategoryList)
.subCategoryList.find(
(stat: any) => stat.name == subList.target.value
).typeList;
}
Is it possible to have an index on a method? Here is a link to the full code on
From your HTML, you are sharing the subCategoryList
instance for the documentSubCategory
select options across the FormGroup
s in the documents
FormArray
.
You should create/use a separate instance for each FormGroup
to avoid overwriting the value when selecting the documentSubCategory
in another FormGroup
.
Using the comIndex
to determine whether the data selection list should fall under which FormGroup
. Your subCategoryList
will be a multi-dimensional array that holds the respective data for the sub-category data selection according to the comIndex
sequence. The concept is the same as the documentType
selection.
subCategoryList: Array<any[]> = [];
typeList: Array<any[]> = [];
changeCategoryList(category: any, comIndex: number) {
this.subCategoryList[comIndex] = this.categoryList.find(
(cat: any) => cat.name == category.target.value
).subCategoryList;
}
changeSubCategoryList(subList: any, comIndex: number) {
let selectedCategory = this.documentFields(comIndex).get('0')?.get('value')?.value;
this.typeList[comIndex] = this.categoryList
.find((cat: any) => cat.name == selectedCategory)
.subCategoryList.find(
(stat: any) => stat.name == subList.target.value
).typeList;
}
When adding the document
, you should add a new empty array to both subCategoryList
and typeList
arrays.
newDocument() {
this.subCategoryList.push([]);
this.typeList.push([]);
return this.fb.group({
name: new FormControl(''),
documentId: new FormControl(''),
documentFields: this.fb.array([]),
});
}
For the HML, you need to provide the comIndex
to the changeCategoryList
and changeSubCategoryList
methods. And retrieve the respective select options with subCategoryList[comIndex]
and typeList[comIndex]
.
<select id="" class="form-select" formControlName="value" (change)="changeCategoryList($event, comIndex)">
<option selected>Select</option>
<option *ngFor="let c of categoryList">
{{c.name}}
</option>
</select>
<select id="" class="form-select" formControlName="value" (change)="changeSubCategoryList($event, comIndex)">
<option selected>Select</option>
<option *ngFor="let s of subCategoryList[comIndex]">{{s.name}}</option>
</select>
...
<select id="" class="form-select" formControlName="value">
<option selected>Select</option>
<option *ngFor="let name of typeList[comIndex]">{{name}}</option>
</select>