components icon indicating copy to clipboard operation
components copied to clipboard

bug(MatDatePicker): change events emitted despite using emitEvents false

Open rraziel opened this issue 3 years ago • 13 comments

Reproduction

https://stackblitz.com/edit/components-issue-xay9ty?file=src%2Fapp%2Fexample-component.ts

  1. Click the "emitEvent: false" button

Expected Behavior

valueChanges should not emit values when setting a value with emitEvent: false

This works correctly for "normal" input components, but not when attaching a date picker.

The reproduction includes a text input and a select for comparison.

Actual Behavior

Using setValue or patchValue with emitEvent set to false has the valueChanges observable emit changes.

Environment

  • Angular: 10.0.3
  • CDK/Material: 10.0.3
  • Browser: Chrome
  • Operating System: Windows

rraziel avatar Aug 06 '20 14:08 rraziel

Marking as "needs discussion" since we should look into how broadly this option should be respected

jelbourn avatar Aug 06 '20 21:08 jelbourn

Just a extra note on the why:

  1. valueChanges subscription that dispatches to an ngrx store
  2. ngrx selector from the store that does a set/patchValue with emitEvent false

This is used as a simple mechanism to keep the state in ngrx, but with the emitEvent ignored it becomes an infinite loop.

rraziel avatar Aug 06 '20 22:08 rraziel

I encountered this bug aswell.

I have a formGroup (attached to a <mat-date-range-*> inside the template):

readonly myRange = new FormGroup({ start: new FormControl({ value: null, disabled: true }), end: new FormControl({ value: null, disabled: true }), });

I do listnen to the value changes, with nothing special, just to console log the value.

this.myRange.valueChanges.subscribe(console.log);

Later in my code I patch the value with emit false.

this.myRange.patchValue({ start: new Date(2020, 9, 5), end: new Date(2020, 9, 10) }, { emitEvent: false });

The value is correctly set, but I don't expect the console.log to show anything.

Edit: added a stack blitz to show the issue: https://stackblitz.com/edit/angular-ivy-hgtnqf?file=src%2Fapp%2Fapp.component.ts

Brutusn avatar Oct 12 '20 09:10 Brutusn

Throwing my few cents in here as well: https://stackblitz.com/edit/angular-fgkwso?file=src/app/datepicker-harness-example.spec.ts

Im synchronising the form state with the ngrx store and relying on the 'emitEvent' flag quite heavily.

Edit: and this bug propagated to Angular@12 :)

Edit2: A little investigation:

when calling form.reset({...values}, {emitEvent: false}), I've pinpointed the place where options get lost. It happens in matDatePicker but the place where the option should be passed is I think in forms. Take a look at this screen:

image

The _forEachChild calls are coming directly from reset() method. Then it goes down to formControl's reset where the value is set. SetValue is called with proper arguments, emitEvent: false, but it invokes _onChange functions and omits the options when passing arguments. image

Then we have onChange which calls MatDatepickerInputBase.writeValue and here no options are even available.

Maybe someone from angular team can reflect on that.

Edit 3: Ugly workaround that seems to work is to filter based on flag set before reset an cleared after (cleared possibly with settimeout)

MikeDabrowski avatar Oct 15 '21 15:10 MikeDabrowski

Same problem here, I run into unwanted valueChanges notifications when doing either FormGroup.PatchValue and FormGroup.SetValue with emitEvent: false. Looks like the controls are the ones firing the evnts.

Shouldn't this option be cascaded? What's the reason otherwise?

vgb1993 avatar Mar 08 '22 13:03 vgb1993

Edit 3: Ugly workaround that seems to work is to filter based on flag set before reset an cleared after (cleared possibly with settimeout)

What if we disconect the FormCobntrols from the FormGroup, then update and then reconect?

vgb1993 avatar Mar 08 '22 13:03 vgb1993

The same issue, fixed it using skipWhile, but it's a pain

YugasVasyl avatar Jul 27 '22 10:07 YugasVasyl

The problem is in interface, we are setting emitEvent option, but FormControl component check old option name emitViewModelChange.

UshakovMaksym avatar Sep 13 '22 13:09 UshakovMaksym

Same issue here with ng14, the emitEvent: false doesn't work properly when it is with mat-date-range-input.

https://stackblitz.com/edit/angular-ivy-gftpsf?file=src/app/app.component.html

weilinzung avatar Sep 29 '22 17:09 weilinzung

image

jziggas avatar Jul 10 '23 20:07 jziggas

Yeah, still an issue. Not sure if setting a flag is guaranteed to work, sync/async, who knows.

jambudipa avatar Nov 17 '23 11:11 jambudipa

Angular 13 and same problem

MIZUDINOV avatar Jan 16 '24 11:01 MIZUDINOV

It's 2024, we're using Angular 17, and this issue is still occurring.

dan-consignly avatar Feb 23 '24 01:02 dan-consignly