components
components copied to clipboard
Bug: Datepicker value change event fires when changing min value of it
Bug, feature request, or proposal:
Bug
What is the expected behavior?
I am not sure it is expected to behave like that or not, but I think that changing min value of datepicker shouldn't fire value changes event of the form group. I changed value of min date inside subscribe method because I want to have mindate dynamically updated. I checked two conditions one with the formgroup where it happens twice all the time and another condition using just formcontrol this issue happens only first time. If I comment out the update of the mindate inside subscribe everything will be okay
What is the current behavior?
Form Group value change happens when changing Datepicker min value via two way binding, Min value update happens inside Subscribe method. This issue causes to fire valuechanges twice
What are the steps to reproduce?
Reproduction is StackBlitz using the formgroup https://stackblitz.com/edit/datepicker-min-date-bug?file=app/datepicker-min-max-example.ts
What is the use-case or motivation for changing an existing behavior?
I think something is odd because different conditions behave differently ( for example as I stated above about formcontrol vs formgroup)
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Angular Material 5.0.0-rc3
@gogakoreli ,
I had the same problem and I used a simple workaround, a filter to simulate the min. This way, valuechanges isn't fired twice.
I added the filter to the input matDatepickerFilter.
<input [matDatepickerFilter]="minFilter"...
minFilter = (d: Date): boolean => {
const from = new Date(this.form.get('curDate').value);
if ( d < from ) {
return false;
}
return true;
}
Here's your modified example: https://stackblitz.com/edit/datepicker-min-date-bug-53war2
Thank you that solves it 😄 It is interesting why [min] binding behaves differently
something to note though: doing it with a filter this way is less efficient, especially for year and multiyear view and it allows the user to navigate arbitrarily far past the min and max (just everything will show as grayed out) min/max actually prevent navigating beyond that page
I faced a similar issue, where changes of min
, max
or matDatepickerFilter
tiggered a valueChange
.
I tried to track down the issue and it seems like the problem is the interaction between the datepicker and the formcontrol:
The MatDatepickerInput
is a Validator
and calls the validatorOnChange
-callback, whenever min
, max
or matDatepickerFilter
changes.
In setUpControl
in angular/forms, the validatorOnChange
-callback is set and it calls updateValueAndValidity
, which causes the value change event.
Any news on this? Is this issue fixed ?
the issue was new Date() will be changed when min and max call every time so don't add new Date() directly minfilter(){ return new Date()//don't do like this }
//do like this currentDate=new Date(); minfilter(){ return this.currentDate; }
I think I got hit by the same issue. I was trying to use Reactive Forms and valueChanges
to watch for any changes in the FormGroup
. Seems that just setting min
triggers two redundant valueChanges
events due to revalidating start & end dates.
https://stackblitz.com/edit/angular-ivy-hnvpqd?file=src/app/app.component.ts
I had the same problem, a simple workaround I used, was to check if the value was actually changed when the valueChanges was triggered. You can achieve this by:
this.FormGroup.controls.dateField.valueChanges.subscribe(value => {
//FormGroup.value container the previous value and value contains the changed value
//if previous value and current value are same then no changed occured. Do Nothing
if (this.FormGroup.value.dateField == value){
return;
}
//Code when value actually changes...
}
Angular 16.2.0 - the issue is still relevant.
first()
rxjs operator solved my issue. My piece of code looks something like this
this.form.get('name')?.valueChanges
.pipe
(
first(),
debounceTime(500),
distinctUntilChanged(),
startWith(''),
filter(value => value.length > 2),
tap(value => {
this.valueSubject.next(value);
}),
switchMap(value => this.userService.findAll({
name: value,
limit: NUMBER_OF_ROWS_LIMIT,
role: UserRole.PARENT,
}),
),
takeUntil(this.destroySubject),
)
.subscribe({
next: (response: { data: User[]; meta: { total_count: number } }) => {
if (!response) {
return;
}
this.state.usersLoaded(response);
},
});
Still relevant. Setting a min or max does not change the control value, so the valueChanges Observable on the control should not emit a new value.
Why don't you just use the filter RxJS operator?
-------- Oprindelig besked -------- 08.05.2024 08.58, Igor Augustynski skrev:
Still relevant. Setting a min or max does not change the control value, so the valueChanges Observable on the control should not emit a new value.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Because filter() is a poor workaround at best, not a fix, and it does not work in every possible scenario. The distinctUntilChanged operator would be better, but a first value to compare to (a) is not always available.