Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to watch all FormControls ValueChanges except specific control?

I have a form that do a computation whenever a control input value changes.

Here is my form_group looks like:

form_group = this.fb.group({
    control1: [],
    control2: [],
    control3: [],
    ...
    control10: [],
});

I can detect all controls value changes via form_group.valueChanges observable, and do a computation. However i want to exclude some of the control that doesn't need to do such an action.

But there is anyway how to not detect the changes on a particular control?

It is very burdensome to write a form_group.get('controlN').valueChanges and do a computation there. I have 5 or more controls in my form.

like image 827
Roel Avatar asked Apr 26 '18 06:04

Roel


3 Answers

You can merge individual valueChanges Observables into one like so :

Observable.merge(
    [ control1.valueChanges,
      control2.valueChanges ]
  ).subscribe(() => {
    // do your computation
  });
like image 55
Roberto Zvjerković Avatar answered Jan 04 '23 18:01

Roberto Zvjerković


Is there a reason why you couldn’t create a FormArray instead of multiple form controls? For example

form_group = this.fb.group({
    'controls': this.fb.array([...])
});

Then you can define a property in your component

get controls(): FormArray {
    return <FormArray>this.form_group.get('control');
}

And then from this you can iterate the form array and subscribe to valueChanges

this.controls.controls.forEach(control => {
    control.valueChanges.subscribe(...)
});

You can then apply some logic in the for each to exclude the controls you do not want to subscribe to

like image 23
Neil Stevens Avatar answered Jan 04 '23 19:01

Neil Stevens


You can do it following way :

combineLatest(this.getControlsForWatch()).subscribe(() => applyFilter());

getControlsForWatch(): Array<Observable<any>> {
        return (
            Object.entries(this.from.controls)
                .filter(([key]) => key !== 'exceptedControl')
                .map(([key]) => this.from.controls[key].valueChanges)
        );
    }

also you can adjust filter for your current task

like image 44
gzn Avatar answered Jan 04 '23 19:01

gzn