Reputation: 935
I want the value of total
box equivalent to the product of price
and quantity
. Without reactive form it was quite easy by using banana in box syntax. How do I achieve the same in reactive-forms
here is my form code
addProductFormGroup(): FormGroup {
return this._formBuilder.group({
productId: ['', Validators.required],
price: ['', Validators.required],
loanTermId: ['', Validators.required],
quantity: ['', Validators.required],
deposit: ['', Validators.required],
total: ['', Validators.required],
});
}
and here is the html of total
input
<mat-form-field appearance="outline" fxFlex="100" class="pr-4">
<mat-label>Total </mat-label>
<input type='number' value='deposit*quantity' formControlName="total" [id]="'total' + i" matInput name="" id="" placeholder="Total" required>
</mat-form-field>
Upvotes: 2
Views: 1864
Reputation: 96
Let me know if this works out (Link to StackBlitz)
ngOnInit(){
this.formGroup = this.fb.group({
quantity : [0 ,[]],
value:[0,[]],
total:[0]
})
this.formGroup.valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(this.isSame)
).subscribe(values =>{
console.log(values)
const {value, quantity} = values;
this.formGroup.patchValue(
{
total : value * quantity
}
)
})}
isSame(prev, next) {
return (prev.value === next.value)
&& (prev.quantity === next.quantity);
}
https://stackblitz.com/edit/angular-8t3qpo?embed=1&file=src/app/app.component.ts
Upvotes: 2
Reputation: 8002
You could subscribe to value changes similar to the following:
// build formgroup then ...
// calculate total
this.formGroup.valueChanges
.pipe(debounceTime(20), takeUntil(this.destroyed$))
.subscribe(value => {
this.calculateLineItemTotal();
});
private calculateLineItemTotal(): number {
// get quantity and rate values
const quantity = +this.formGroup.controls.LineQuantity.value;
const rate = +this.formGroup.controls.LineRate.value;
// verify if blank
if (!quantity || !rate) {
this.formGroup.controls.LineTotal.setValue("", {
emitEvent: false
});
return 0;
}
this.formGroup.controls.LineTotal.setValue((quantity * rate).toFixed(2), {
emitEvent: false
});
return quantity * rate;
}
Warning - This gets ugly fast (think patching value when in edit mode) so best avoided if possible as alluded to be Jenson in the comments.
Upvotes: 1
Reputation: 9124
value='33' // dont do that
addProductFormGroup(): FormGroup {
return this._formBuilder.group({
productId: ['', Validators.required],
price: ['', Validators.required],
loanTermId: ['', Validators.required],
quantity: ['', Validators.required],
deposit: ['', Validators.required],
total: ['33', Validators.required], // do that!
});
}
Edited:
Based on your response, I'd say remove total
from the formGroup since it is not actually a user input. Rather do something liek this:
total$: Observable<number>;
this.total$ = this.productFormGroup.valueChanges.pipe(
map(formValue => +formValue.quantity * +formValue.price)
)
<div>Total: {{ total$ | async }}</div>
Upvotes: 3
Reputation: 784
I think you just need to do something like
public get total(): any {
if (this.form.get('price').value && this.form.get('quantity').value) {
return this.form.get('price').value * this.form.get('quantity').value;
}
return '';
}
Note : You need to create form and need to store formGroup return value in that
Upvotes: 1