Description
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
I have a widget that uses mat-slider
. This widget takes a value as an input and sets it to the form control bound to the slider:
// template
<mat-slider>
<input matSliderThumb [formControl]="sliderValue">
</>
// component
@Input() value: number
sliderValue = new FormControl(0, {nonNullable: true})
ngOnChanges() {
this.sliderValue.setValue(this.value) // <-- this
// derived value used in the template
this.isDefaultValue = this.value === 0
}
Looks like the .setValue
call breaks change detection. The isDefaultValue
value is properly derived (as per console.log output), but is not reflected in HTML. It will get updated after the next interaction with the widget (which triggers change detection), or after manually calling changeDetectorRef.detectChanges()
.
This happens with a single-handle or a two-handle slider.
It only happens when the value is bound to the slider via a form control. If I pass the value as a property binding instead ([value]="sliderValue.value"
), everything works fine.
Also moving the isDefaultValue
calculation up to be before the .setValue
call magically solves it, too.
Reproduction
StackBlitz link: https://stackblitz.com/edit/xsoedg?file=src%2Fexample%2Fapp-widget.component.ts
- Click the "set to 2" button
Expected Behavior
- Slider value is printed as "2"
- Slider default state is printed as "false"
- The slider turns blue
Actual Behavior
- Slider value is printed as "2" (correct)
- Slider default state is printed as "true" (incorrect)
- The slider remains gray (incorrect)
Environment
- Angular: 16
- CDK/Material: 16
- Browser(s): Firefox, Chrome
- Operating System (e.g. Windows, macOS, Ubuntu): macOS