Reputation: 265
I would like to get the values of an input in each row and get the sum of these rows.
my HTML:
<ng-container formArrayName="cap_values">
<tbody *ngFor="let item of capValues.controls; let i=index" [formGroupName]="i">
<tr>
<td class="freeze-first-col"><input type="text" (blur)="getName(item.value.name)" formControlName="name"></td>
<td><input type="number" formControlName="fdnTotalShares"</td>
</tr>
</tbody>
</ng-container>
my .ts:
ngOnInit() {
this.form = this.fb.group({
cap_values: this.fb.array([this.fb.group({
name: '',
fdnTotalShares: '',
}
)])
})
}
How do I iterate over each value in the array and sum it? I have seen .valueChanges
but am not entirely sure how to use it.
Upvotes: 1
Views: 5942
Reputation: 3083
There are multiple ways you can do this, I'll write down some:
1st way:
get capValues(): FormArray {
return this.form.get('cap_values') as FormArray;
}
getSum() {
this.sum = this.capValues.value.reduce((prev, next) => prev + +next.fdnTotalShares, 0);
// OR
// this.sum = this.capValues.getRawValue().reduce((prev, next) => prev + +next.fdnTotalShares, 0);
}
Notice the +
sign in +next.fdnTotalShares
, that is not a mistake, it is to make sure that you get the sum of numbers (assuming fdnTotalShares
will always be a number) instead of getting string concatenation.
2nd way:
this.sum = 0;
this.capValues.value.forEach(x => {
this.sum += +x.fdnTotalShares;
});
Instead of value
you can use getRawValue()
if you have some controls that are disabled and you want to include them in your calculation.
Here is a stackblitz example demonstrating this (I also included the difference with enabled
and disabled
controls).
EDIT: To answer you question in the comment, this is similar as the sum example I wrote above:
multiplyAndStore() {
const multiplicationRes = this.capValues.value.reduce((prev, next) => prev * +next.fdnTotalShares, 1);
// Assuming that "formControlName" for multiplication result input is 'multiplyResult'
this.form.get('multiplyResult').setValue(multiplicationRes);
// You can also use "patchValue" method instead of "setValue"
// this.form.get('multiplyResult').patchValue(multiplicationRes);
}
I have updated the stackblitz example so you can see this in action.
Hope this helps.
Upvotes: 6
Reputation: 8660
Use the valueChanges
Observable to achieve this.
In your component, once you create your form, subscribe to the valueChanges
in your form array cap_values
.
import { Subscription } from 'rxjs';
total: number = 0;
subscription: Subscription;
ngOnInit() {
// Create your form here
this.subscription = this.capValues.valueChanges.subscribe(data => {
this.total = data.reduce((a,b) => a + +b.fdnTotalShares, 0)
});
}
get capValues() {
return this.form.get('cap_values') as FormArray;
}
Now wherever you want to display the total in your template just use {{total}}
and it will dynamically update as you change values in the fdnTotalShares
input.
Lastly, do not forget to unsubscribe from valueChanges
. This is why I have introduced the subscription
variable as seen in the code snippet above.
ngOnDestroy() {
this.subscription.unsubscribe();
}
Here is a simple working example on StackBlitz.
Upvotes: 1
Reputation: 5742
Here I have Tried . One
console.log(this.form.length);
console.log(this.form.value);
Upvotes: 0
Reputation: 1932
You can loop through your form controls
let total = 0;
form.controls.foreach(data => {
total += data.fdnTotalShares.value;
})
To make sure proper form control is being get use console log
Upvotes: 0