Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

patchValue with { emitEvent: false } triggers valueChanges on Angular 4 formgroup

I have a formbuilder group and am listening for changes with valueChanges and triggering a save function followed by refresh function on the form:

 this.ticketForm.valueChanges.debounceTime(1000).distinctUntilChanged()
 .subscribe(data => {
   this.saveTicket();
   this.refreshTicket();
 })

I am then reloading the form and repatching the data to form fields (and elsewhere on the page, particularly a change log) with patchValue, e.g.:

    this.ticketForm.patchValue(ticket, { emitEvent: false });

however, this causes an infinite loop of saves of the form despite emitEvent : false.

Is this an Angular 4/Ionic 3 bug or a misunderstanding on my part?

like image 678
larpo Avatar asked Jul 21 '17 15:07

larpo


People also ask

Does patchValue trigger valueChanges?

So basically when we call setValue, patchValue, disable, enable control it triggers value change by default. If we had not setted emitEvent to false, it would trigger valueChange so parent form would trigger unnecessary api which we want to avoid here.

What is the difference between setValue and patchValue?

SetValue Vs PatchValue The difference is that with setValue we must include all the controls, while with the patchValue you can exclude some controls.

What is FormGroup patchValue?

FormGroup.patchValue The patchValue accepts the object with control names as keys. If the supplied object does not contain all the form controls as keys of this FormGroup object, patchValue sets new value only to those form controls which are available in supplied object .

What is onlySelf angular?

onlySelf : When true, each change only affects this control, and not its parent. Default is false. emitEvent : When true or not supplied (the default), both the statusChanges and valueChanges observables emit events with the latest status and value when the control is reset. When false, no events are emitted.


4 Answers

Try adding onlySelf: true along with the emitEvent: false in this way:

this.ticketForm.patchValue(ticket, {emitEvent: false, onlySelf: true});
like image 164
Lakshay Avatar answered Oct 02 '22 16:10

Lakshay


Can't comment because of rep, so I will post it as an answer to @Craig Wayne.

emitEvent:false works only if you are listening to value changes on the form control with:

this.form.valueChanges.controlName.subscribe(val => doSomething(val));

if you are binding to model changes on the element event is emitted regardless:

<input (ngModelChange)="doSomething($event)"/>
like image 33
enjoyYourProgramming Avatar answered Oct 02 '22 18:10

enjoyYourProgramming


While working with Angular 9.1.13 I had been facing the same problem. Tried to use the FormControl.setValue, and FormGroup.patchValue APIs, using also the suggested params {emitEvent: false, onlySelf: true} in all possible combinations. The valueChanges observable is was still being triggered.

The only thing that worked for me eventually was :

myForm.disable();
myForm.patchValue({myControl: ''}, {onlySelf: true, emitEvent: false});
myForm.enable();
like image 30
ktsangop Avatar answered Oct 02 '22 17:10

ktsangop


As a workaround, i add skip to rxjs pipe

this.form.valueChanges
    .pipe(skip(1)).subscribe();
like image 35
Wei Lun Avatar answered Sep 18 '22 14:09

Wei Lun