Reputation: 2275
I have a reactive form that contains an Array of objects with 2 fields. I am trying to do a simple multiplication between those two fields whose result will be stored in a third field. I subscribed with valueChanges
to the changes of the Array and it works, but the values of the form does not listen to those changes.
Here's an example in Stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts
What is the correct way to subscribe to changes in an Array containing objects?
formDoyle: FormGroup;
largo: number;
resultPiesTablares = 0;
constructor( private fb: FormBuilder ) { }
ngOnInit(): void {
this.formDoyle = this.fb.group({
calculos: this.fb.array([
this.getCalculo()
])
});
this.formDoyle.get('calculos')?.valueChanges.subscribe(res => {
const control = <FormArray>this.formDoyle.controls['calculos'];
this.resultPiesTablares = 0;
for (let i in res) {
let diametroMenor = res[i].diametroMenor;
let largo = res[i].largo;
let resultPiesTablares = diametroMenor * largo;
control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
}
});
}
private getCalculo() {
const numberPatern = '^[0-9.,]+$';
return this.fb.group({
diametroMenor: ['', [Validators.required, Validators.pattern(numberPatern)]],
largo: ['', [Validators.required, Validators.pattern(numberPatern)]],
subTotal: ['']
});
}
agregarCalculo() {
const control = <FormArray>this.formDoyle.controls['calculos'];
control.push(this.getCalculo());
}
removeCalculo(i: number) {
const control = <FormArray>this.formDoyle.controls['calculos'];
control.removeAt(i);
}
Upvotes: 0
Views: 3307
Reputation: 2275
In the end what worked for me was to subscribe to the changes of each value:
See updated stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts
for (let i in calculos) {
control.at(+i).get('diametroMenor')?.valueChanges.subscribe( res => {
let resultPiesTablares = res * calculos[i].largo;
control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
});
control.at(+i).get('largo')?.valueChanges.subscribe( res => {
let resultPiesTablares = calculos[i].diametroMenor * res;
control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
});
}
Upvotes: 1
Reputation: 14002
You are not getting the new value of subTotal in your valueChanges listener because you put { onlySelf: true }
which is a good thing because otherwise you would get an infinite loop.
If you want to listen to the subTotal you need to subscribe to it:
control.at(0).get('subTotal').valueChanges.subscribe(res => {
console.log('subTotal:', res)
});
Upvotes: 0