'valueChange in formArray inside a formArray
i have a form that contains a formArray (FinYearArray) that on his turn contains another formArray (RecipientArray) both these FinYearArray and RecipientArray contains a formControl for the amount, everytime there is a change on these fields the total should be calculated for the financial years and for the recipient countries by financial year. For the total of the recipients i created a formControl in the FinYearArray named 'RecipientTotal'
//structure of the form
{
"FinYearArray": [
{
"FinYear": 2022,
"FinYearAmount": 0,
"RecipientTotal": 0,
"RecipientArray": [
{
"CtryDesc": "",
"Amount": 0,
},
{
"CtryDesc": "",
"Amount": 0,
}
],
},
{
"FinYear": 2023,
"FinYearAmount": 0,
"RecipientTotal": 0,
"RecipientArray": [
{
"CtryDesc": "",
"Amount": 0,
}
],
}
],
"ProjectCode": "",
}
in my ngOnInit() i have this code to check when there are changes in the FinYearArray formArray and automaticcaly also in the RecipientArray formArray because it is inside the other formArray
//function that calculates the totals for fin year and recipients/fin year
this.formDetailReport.get('FinYearArray').valueChanges.subscribe(values => {
this.myFinYearTotal = 0;
const ctrl = <FormArray>this.formDetailReport.controls['FinYearArray'];
//loop trough fin years
ctrl.controls.forEach(x => {
let parsed = Number(x.get('FinYearAmount').value);
this.myFinYearTotal += parsed;
});
//loop through recipient countries for each financial year
for (let i = 0; i < ctrl.controls.length; i++) {
this.myRecipientTotal = 0;
const recipientFormArray = <FormArray>ctrl.controls[i].get('RecipientArray');
recipientFormArray.controls.forEach(x => {
let parsed = Number(x.get('Amount').value);
this.myRecipientTotal += parsed;
});
console.log('total : ' + i + ' amount : ' + this.myRecipientTotal );
// when using this code i get the error at the end of this mail
this.formDetailReport.controls['cFinYearGroup']['controls'][i].controls.cRecipientTotal.setValue(this.myRecipientTotal);
// ctrl[i].controls.cRecipientTotal.setValue(this.myRecipientTotal);
}
this.ref.detectChanges();
});
but i get this error
// error when i try to assign the calculate value to the formControl
core.js:4442 ERROR RangeError: Maximum call stack size exceeded
at EuiInputNumberComponent.ngDoCheck (eui-components-next.js:11713:1)
at callHook (core.js:3285:1)
at callHooks (core.js:3251:1)
at executeInitAndCheckHooks (core.js:3203:1)
at refreshView (core.js:7395:1)
at refreshEmbeddedViews (core.js:8481:1)
at refreshView (core.js:7404:1)
at refreshComponent (core.js:8527:1)
at refreshChildComponents (core.js:7186:1)
at refreshView (core.js:7430:1)
i think this comes because every time i update the recipient total (cRecipientTotal formControl) this piece of code is re-executed because there is a valueChange inside the formArray
isn't there a way that this valueChange is only watching the FinYearAmount formControl inside the formArray instead of watching all the fields of this formArray? and afterwords watching the formcontrol Amount in the RecipientArray
Solution 1:[1]
When updating an AbstractControl which has a valueChanges
listener attached and you don't want to retrigger it (causing the infinite loop you are suffering from), you can add a configuration object to your setValue/patchValue
call:
myFormControl.setValue(value, { emitEvent: false });
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Will Alexander |