FairPluto
FairPluto

Reputation: 737

Is there a way to prevent formControl from triggering event?

I have 3 fields linked with forms which type is number, when I modify field A, it modifies field B and C, when I modify field B it modifies field A and C and when I modify field C it modifies field A and B accordingly.

my component is as below :

this.form= this.formBuilder.group({
   fieldA: new FormControl(this.valueA),
   fieldB: new FormControl(this.valueB),
   fieldC: new FormControl(this.valueC),
});

onFieldAchanged() {
   //Do some calculs
   this.form.get('fieldB').setValue(x);
   this.form.get('fieldC').setValue(y);
}

onFieldBchanged() {
   //Do some calculs
   this.form.get('fieldA').setValue(x);
   this.form.get('fieldC').setValue(y);
}

onFieldCchanged() {
   //Do some calculs
   this.form.get('fieldA').setValue(x);
   this.form.get('fieldB').setValue(y);
}

and my template as below :

<input formControlName="fieldA" type="number" class="form-control" (ngModelChange)="onFieldAchanged()"/>
<input formControlName="fieldB" type="number" class="form-control" (ngModelChange)="onFieldBchanged()"/>
<input formControlName="fieldC" type="number" class="form-control" (ngModelChange)="onFieldCchanged()"/>

The problems come when you modify one of the field, it goes into a loop and makes the app crash.

I already tried to add the parameter emitEvent: false in my setValue() but it changed nothing

So my question: Is there a way to prevent the triggering of the other functions ? When I modify fieldA I just want to enter in my onFieldAchanged() function and set the two others values, no more.

Thank you for your help

Upvotes: 2

Views: 6927

Answers (3)

bryan60
bryan60

Reputation: 29335

there sure is:

first, instead of using (ngModelChange), use valueChanges observable:

this.form.get('fieldA').valueChanges.subscribe(v => this.onFieldAchanged());
this.form.get('fieldB').valueChanges.subscribe(v => this.onFieldBchanged());
this.form.get('fieldC').valueChanges.subscribe(v => this.onFieldCchanged());

then, add the emitEvent option into your setValue fuctions to stop their valueChanges from emitting:

onFieldAchanged() {
   //Do some calculs
   this.form.get('fieldB').setValue(x, {emitEvent: false});
   this.form.get('fieldC').setValue(y, {emitEvent: false});
}

the issue is mixing ngModel with reactive forms. gotta choose one.

Upvotes: 14

Ivan Mihaylov
Ivan Mihaylov

Reputation: 433

You can easily pass a parameter in your onFieldXchanged() function in the template and check for this string to see if the event was triggered from an input being typed or from one of the other eventriggers. Just make a guard.

Upvotes: 0

NiallMitch14
NiallMitch14

Reputation: 1229

Weird, I actually did something similar to this myself:

What I did was make two form groups:

    this.groupA = this.formBuilder.group({
        fieldA: new FormControl(''),
    });

    this.groupB = this.formBuilder.group({
        fieldB: new FormControl(''),
    });

Then I have it set that fieldA's value changes causes fieldB's value to change:

ngOnInit(){
    this.groupA.get('fieldA').valueChanges.subscribe(val => {
        this.groupB.get('fieldB').setValue(val);
    });
}

Then in my template, fieldA's value is set to fieldB's to complete the sync:

<input matInput placeholder="Field A:" formControlName="fieldA [value]="groupB.get('fieldB').value">

Upvotes: -1

Related Questions