0

I have a reactive form that contains an Array of objects with 2 fields. I am trying to do a simple multiplication between those two fields whose result will be stored in a third field. I subscribed with valueChanges to the changes of the Array and it works, but the values of the form does not listen to those changes.

Here's an example in Stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts

enter image description here

What is the correct way to subscribe to changes in an Array containing objects?

formDoyle: FormGroup;
  largo: number;
  resultPiesTablares = 0;

  constructor( private fb: FormBuilder ) { }

  ngOnInit(): void {

    this.formDoyle = this.fb.group({
      calculos: this.fb.array([
        this.getCalculo()
      ])
    });

    this.formDoyle.get('calculos')?.valueChanges.subscribe(res => {
      const control = <FormArray>this.formDoyle.controls['calculos'];
      this.resultPiesTablares = 0;
      for (let i in res) {
        let diametroMenor = res[i].diametroMenor;
        let largo = res[i].largo;
        let resultPiesTablares = diametroMenor * largo;
        control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
      }
    });
    
  }

  private getCalculo() {
    const numberPatern = '^[0-9.,]+$';
    return this.fb.group({
      diametroMenor: ['', [Validators.required, Validators.pattern(numberPatern)]],
      largo: ['', [Validators.required, Validators.pattern(numberPatern)]],
      subTotal: ['']
    });
  }

  agregarCalculo() {
    const control = <FormArray>this.formDoyle.controls['calculos'];
    control.push(this.getCalculo());
  }

   removeCalculo(i: number) {
    const control = <FormArray>this.formDoyle.controls['calculos'];
    control.removeAt(i);
  }

2 Answers 2

1

In the end what worked for me was to subscribe to the changes of each value:

See updated stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts

for (let i in calculos) {
    control.at(+i).get('diametroMenor')?.valueChanges.subscribe( res => {
      let resultPiesTablares = res * calculos[i].largo;
      control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
    });

    control.at(+i).get('largo')?.valueChanges.subscribe( res => {
      let resultPiesTablares = calculos[i].diametroMenor * res;
      control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
    });
  }
Sign up to request clarification or add additional context in comments.

Comments

0

You are not getting the new value of subTotal in your valueChanges listener because you put { onlySelf: true } which is a good thing because otherwise you would get an infinite loop.

If you want to listen to the subTotal you need to subscribe to it:

control.at(0).get('subTotal').valueChanges.subscribe(res => {

        console.log('subTotal:', res)

});

1 Comment

Thanks @Rachid , I have updated my answer based on your suggestion

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.