Good evening, I have a problem I am using a reactive form, with FormArray, I have a button to add 2 options as many times as necessary, the problem is that the options are matselects and in one of these selects I use an event (change), the problem is that adding the options for the first time the onchange works normal, but when adding the options more than 2 times the values that were previously selected in the matselects change because the onchange of the created select is re-executed. I would like to know if there is a way to use that event independently in each iteration of the formArray
Component.ts
alicuotaForm: FormGroup;
value = this.fb.group({
manzana: ['', Validators.required],
villa: ['', Validators.required],
});
nregistros: number;
ngOnInit() {
this.alicuotaForm = this.fb.group({
times: this.fb.array([]),
});
}
//event onchange
getVillas(value) {
console.log('valor: ', value.value);
this.filtro = this.villas.filter((x) => x.manzana == value.value);
}
addGroup() {
const val = this.fb.group({
manzana: ['', Validators.required],
villa: ['', Validators.required],
});
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.push(val);
this.nregistros = alicuotaForm.length;
}
removeGroup(index) {
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.removeAt(index);
}
trackByFn(index: any, item: any) {
return index;
}
component.html
<div class="container">
<div class="row">
<div class="col-col-6">
<label class="transparente"></label>
<button (click)="addGroup()" type="button" class="btn btn-success">
Agregar Campos
</button>
</div>
<br />
<form [formGroup]="alicuotaForm">
<ng-container
formArrayName="times"
*ngFor="
let time of alicuotaForm.controls.times?.value;
let i = index;
trackBy: trackByFn
"
>
<ng-container [formGroupName]="i" style="margin-bottom: 10px;">
Iteracion {{ i + 1 }}
<div class="col-col-6">
<label>Manzana</label>
<select
formControlName="manzana"
class="form-control custom-select"
(change)="getVillas($event.target)"
>
>
<option *ngFor="let ur of manzanas">
{{ ur.manzana }}
</option>
</select>
</div>
<br />
<div class="col-sm">
<label>Villa</label>
<select formControlName="villa" class="form-control custom-select">
<option *ngFor="let ur of filtro" value="{{ ur.villa }}">
{{ ur.villa }}
</option>
</select>
</div>
<br />
------------------------------------------------------------------------<br /> </ng-container
></ng-container>
</form>
</div>
</div>
I don't know what I could do or what would you recommend me to solve my problem, thank you very much
code in stackblitz Stackblitz
You have to create the separate value for filtro you can get help from the following code
HTML
<hello name="{{ name }}"></hello>
<p>Start editing to see some magic happen :)</p>
<div class="container">
<div class="row">
<div class="col-col-6">
<label class="transparente"></label>
<button (click)="addGroup()" type="button" class="btn btn-success">
Agregar Campos filtro
</button>
</div>
<br />
<form [formGroup]="alicuotaForm">
<ng-container
formArrayName="times"
*ngFor="
let time of alicuotaForm.controls.times?.value;
let i = index;
trackBy: trackByFn
"
>
<ng-container [formGroupName]="i" style="margin-bottom: 10px;">
Iteracion {{ i + 1 }}
<div class="col-col-6">
<label>Manzana</label>
<select
formControlName="manzana"
class="form-control custom-select"
(change)="getVillas($event.target, i)"
>
>
<option *ngFor="let ur of manzanas">
{{ ur.manzana }}
</option>
</select>
</div>
<br />
<div class="col-sm">
<label>Villa</label>
<select formControlName="villa" class="form-control custom-select">
<option *ngFor="let ur of filtro[i]" value="{{ ur.villa }}">
{{ ur.villa }}
</option>
</select>
</div>
<br />
------------------------------------------------------------------------<br /> </ng-container
></ng-container>
</form>
Typescript
import { Component, VERSION } from '@angular/core';
import {
FormControl,
FormGroup,
FormBuilder,
FormArray,
Validators,
FormGroupDirective,
} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
villas = [
{ manzana: '1', villa: '10' },
{ manzana: '1', villa: '20' },
{ manzana: '1', villa: '30' },
{ manzana: '2', villa: '40' },
{ manzana: '2', villa: '50' },
{ manzana: '2', villa: '60' },
{ manzana: '3', villa: '70' },
{ manzana: '3', villa: '80' },
{ manzana: '3', villa: '90' },
];
filtro: any[]=[];
manzanas = [{ manzana: '1' }, { manzana: '2' }, { manzana: '3' }];
alicuotaForm: FormGroup;
value = this.fb.group({
manzana: ['', Validators.required],
villa: ['', Validators.required],
});
nregistros: number;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.alicuotaForm = this.fb.group({
times: this.fb.array([]),
});
}
getVillas(value,index) {
console.log('valor: ', value.value);
this.filtro[index] = this.filtro[index].filter(x => x.manzana === value.value);
}
addGroup() {
const val = this.fb.group({
manzana: ['', Validators.required],
villa: ['', Validators.required],
});
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.push(val);
this.nregistros = alicuotaForm.length;
this.filtro.push(null);
this.filtro[this.nregistros-1]=[...this.villas];
}
removeGroup(index) {
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.removeAt(index);
}
trackByFn(index: any, item: any) {
return index;
}
}