Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Reactive Forms valueChanges - UI changes only

The Angular FormControl has a valueChanges Observable that states:

Emits an event every time the value of the control changes, in the UI or programmatically.

Is there a way to set the FormControl to ignore programmatic value changes? (Basically the equivalent of OneWayToSource binding in .NET)

Specifically, the issue I'm facing is that my valueChanges subscription, I'm updating a bunch the values bound to a bunch of other controls, which then causes valueChanges to fire for all of them as well, which is problematic as the actions they perform in their valueChanges handlers conflicts with the control the user actually touched.

like image 730
MgSam Avatar asked Apr 16 '18 15:04

MgSam


People also ask

What does ValueChanges return?

The ValueChanges is an event raised by the Angular forms whenever the value of the FormControl, FormGroup or FormArray changes. It returns an observable so that you can subscribe to it. The observable gets the latest value of the control. It allows us to track changes made to the value in real-time and respond to it.

Should I unsubscribe from ValueChanges?

Yes, you do. Note that you do not need to unsubscribe from http calls because they auto-complete themselves. You must unsubscribe to prevent memory leaks and to avoid unexpected side-effects in your application.

Are reactive forms asynchronous?

Template-driven forms are asynchronous in nature, whereas Reactive forms are mostly synchronous. In a template-driven approach, most of the logic is driven from the template, whereas in reactive-driven approach, the logic resides mainly in the component or typescript code.


2 Answers

You can skip emitting the valueChange event by passing the option { emitEvent: false } to the setValue call.

setValue(value: any, options: {
    onlySelf?: boolean;
    emitEvent?: boolean;
    emitModelToViewChange?: boolean;
    emitViewToModelChange?: boolean;
} = {}): void

Also you might want to take a look at other options.

If onlySelf is true, this change will only affect the validation of this FormControl and not its parent component. This defaults to false.

If emitEvent is true, this change will cause a valueChanges event on the FormControl to be emitted. This defaults to true (as it falls through to updateValueAndValidity).

If emitModelToViewChange is true, the view will be notified about the new value via an onChange event. This is the default behavior if emitModelToViewChange is not specified.

If emitViewToModelChange is true, an ngModelChange event will be fired to update the model. This is the default behavior if emitViewToModelChange is not specified.

Docs

like image 142
Tomasz Kula Avatar answered Oct 02 '22 07:10

Tomasz Kula


You can pass { emitEvent: false } as options for the below reactive form methods to prevent them from triggering the valueChanges event

this.form.patchValue(value, { emitEvent: false })
this.form.setValue(value, { emitEvent: false })
this.form.controls.email.updateValueAndValidity({ emitEvent: false })
this.form.disable({ emitEvent: false })

yes disable triggers the valueChanges event

PS: above this.form is a reactive form

Read this excellent post, it'll answer all your questions and even give some great insights on reactive forms:

https://netbasal.com/angular-reactive-forms-tips-and-tricks-bb0c85400b58

like image 43
tejas n Avatar answered Oct 02 '22 05:10

tejas n