I'm attempting to calculate a total or other value based on a particular value in a FormArray.
I'm finding that when subscribing to valueChanges
and attempting to pass the whole array to something like reduce
, the "new value" isn't present on the parent FormGroup.
Original Example on StackBlitz
Sample:
this.frm.get('arr')['controls'][i].valueChanges
.subscribe((newVal) => {
this.frm.get('total').patchValue(
this.frm.get('arr').value.reduce((acc, curr) => {
return acc + curr.v;
}, 0)
)
});
If arr
has values [0, 1, 2, 3, 4]
and I change the first value to 1
, I still get 10
instead of 11
.
this.frm.get('arr').value
shows all the initial values and not the updated values.
I'm fairly new to Reactive Forms so I'm sure I'm just missing something fundamental here.
UPDATE (Have a solution, but I'm still lacking understanding):
I'd really love to know why I'm not able to subscribe to changes to the whole array like Eliseo had suggested.
I'm also interested in why there is such a difference between where I use .value
- If the whole point of Reactive Forms are to be Model Driven and then pass frm.value
to your Submit function, then why is .value
so inconsistent throughout the form hierarchy?
UPDATE 2
Updated StackBlitz Solution with guidance from Eliseo after his update
I've found a solution that I feel pretty good about. It doesn't use controls
anywhere and feels very clean. Eliseo's suggested approach pushed me to try this out. I believe the important thing is casting to a FormArray
and executing any push
on that. This keeps the parent
field tied to the rest of your FormGroup
or FormArray
thus it stays included in the valueChanges
event.
I now believe using controls
is an anti-pattern to Angular Reactive Forms, but I need to search for more guidance on that topic.