How can I subscribe to formGroup changes and calculate one of properties from two other?

Viewed 309

I have function creates formGroup and I need to calculate one of field from two others: sum = price * count. How can I do that?

public createService = (): FormGroup => {
    const group = this.fb.group({
      name: [''],
      measure: [''],
      count: [''],
      price: [''],
      sum: ['']
    });

    group.valueChanges.subscribe(res => {
      // group.patchValue({...res, sum: +res.price * +res.count});
      // res.sum = +res.price * +res.count;
      console.log(res);
    });

    return group;
  }
4 Answers

If you subscribe to the whole form and update the value of sum inside value changes there will be an infinite call cycle to value changes. Instead you should subscribe to individual form controls.

import { merge } from 'rxjs/observable/merge';

public createService = (): FormGroup => {
   const group = this.fb.group({
     name: [''],
     measure: [''],
     count: [''],
     price: [''],
     sum: ['']
   }); 

   merge(
     group.get('count').valueChanges,
     group.get('price').valueChanges
   ).subscribe(res => {
     this.calculateSum(group);
   });
}

calculateSum(group) {
  const count = +group.get('count').value;
  const price = +group.get('price').value;
  group.get('sum').setValue(count + price);
}

You don't have to subscribe the whole form group. Just look for changes on price and count fields. Something like below;

 this.group.get('price').valueChanges.subscribe(value => {
      this.price = value;
      this.calculateSum();
  });

this.group.get('count').valueChanges.subscribe(value => {
      this.count = value;
      this.calculateSum();
  });

calculateSum() {
   sum = this.price*this.count;
   this.group.get('sum').setValue(sum);
}
import { combineLatest } from 'rxjs';

   combineLatest(
     this.group.get('count').valueChanges,
     this.group.get('price').valueChanges
   ).subscribe(([count, price]) => {
       this.testForm.get('sum').setValue(+count + +price);
   });

You can set the attribute value for the field sum like {{form.count + form.price}}. Now I can't test it, but it's something like that.

Related