I am using Reactive Forms and trying to dynamically perform a math calculation once a formGroup becomes valid.
I have a btn to add more form groups by using formArray and I have another btn to do the calculation when it’s clicked. However, I want the calculation to be done and displayed once all the input fields for a form group are input and valid.
I was trying to us ngIf to check if the formGroup is valid then call a function, pass it the index number (for grabbing the necessary form controls) and then do the calculation:
HTML
<div>
Sum:
<ng-container *ngIf="roundInputs.get(roundCount + '')?.valid ? calculateHandicapBtnClick(roundCount) : null">
<span *ngFor="let total of roundTotal; let sumCount = index">
<span *ngIf="roundCount === sumCount">
{{total}}
</span>
{{total}}
</span>
</ng-container>
</div>
TS
calculateHandicapBtnClick(roundNumber: number) {
this.roundTotal = [];
let tempArray = [];
let eighteeenHoleScore = this.roundInputs.controls[roundNumber].get('eighteenHoleScore')?.value;
let nineHoleScore = this.roundInputs.controls[roundNumber].get('nineHoleScore')?.value;
let total = eighteeenHoleScore + nineHoleScore
this.roundTotal.push(total);
// this.roundTotal.splice(roundNumber, 0, total)
// this.roundTotal.push(eighteeenHoleScore + nineHoleScore)
// this.roundInputs.controls.forEach((control) => {
// eighteeenHoleScore = control.get('eighteenHoleScore')?.value
// nineHoleScore = control.get('nineHoleScore')?.value
// this.roundTotal.push(eighteeenHoleScore + nineHoleScore)
// })
}
Here is what I have for how I have the formGroups setup along with how the addRound() works:
get roundInputs(): FormArray{
return <FormArray>this.roundForm.get('roundInputs')
}
ngOnInit(): void {
this.roundForm = this.fb.group({
roundInputs: this.fb.array([ this.buildRoundForm() ])
})
};
addRound() {
this.roundInputs.push(this.buildRoundForm())
}
I can’t seem to get the total to come together and display on the page. In the console I am seeing my logs double after the form becomes valid and when I click out of the input and then clicking elsewhere on the page. From what I have read I probably shouldn’t be calling a function there in the HTML as change detection running will cause it to run multiple times (where as if I tie it to a btn I don’t have as much of an issue). You can also see I have tried various other things that are commented out such as looping through all the form controls or trying to splice and put the total in a specific position in the array (I am using an array of values to then loop through and populate those values onto the page)
Another thing I read was to possibly create a custom pipe where it takes in and does the arithmatic and displays it on the page. I also came across maybe doing something with the ngOnInit or ngOnChanges or even possibly trying to force change detection. I haven’t really found anything that works so looking for some input.
Here is a screenshot of the app and what I am trying to attempt. You can ignore the ‘Calculate Handicap’ btn as I am trying to phase that out and replace it with the above scenario
2
Answers
Do this in the Typescript part, subscribe to status change of the form, or a single form field, and perform desired calculations.
you can use
always you return true in your function
But it’s better, as Yogi suggest it’s better peformance use statusChanges. I imagine you have a function that return the formGroup and a getter for your array
Well if you don’t want subscribe and unsubscribe, you can to have an array of "observables"
And fill the array when you create the form
So you can use in your .html