Skip to content

Commit 1a03257

Browse files
authored
fix(material-experimental/mdc-slider): fix a few null pointer exceptions (#23659)
Fixes a few null pointer errors if: 1. `setDisabledState` is called too early. This can't happen at the moment, but it showed up when trying to fix something in `@angular/forms` and it may become an issue in the future. 2. The component is destroyed before the initialization is complete. This showed up while investigating the first error.
1 parent cfd8908 commit 1a03257

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

src/material-experimental/mdc-slider/slider.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ describe('MDC-based MatSlider', () => {
4646
}
4747

4848
describe('standard slider', () => {
49+
let fixture: ComponentFixture<StandardSlider>;
4950
let sliderInstance: MatSlider;
5051
let inputInstance: MatSliderThumb;
5152

5253
beforeEach(
5354
waitForAsync(() => {
54-
const fixture = createComponent(StandardSlider);
55+
fixture = createComponent(StandardSlider);
5556
fixture.detectChanges();
5657
const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
5758
sliderInstance = sliderDebugElement.componentInstance;
@@ -98,6 +99,12 @@ describe('MDC-based MatSlider', () => {
9899
expect(inputInstance.value).toBe(10);
99100
sliderInstance._elementRef.nativeElement.style.marginLeft = 'initial';
100101
});
102+
103+
it('should not throw if destroyed before initialization is complete', () => {
104+
fixture.destroy();
105+
fixture = TestBed.createComponent(StandardSlider);
106+
expect(() => fixture.destroy()).not.toThrow();
107+
});
101108
});
102109

103110
describe('standard range slider', () => {

src/material-experimental/mdc-slider/slider.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -852,32 +852,32 @@ export class MatSlider
852852

853853
/** Sets the disabled state based on the disabled state of the inputs (ControlValueAccessor). */
854854
_updateDisabled(): void {
855-
const disabled = this._inputs.some(input => input._disabled);
855+
const disabled = this._inputs?.some(input => input._disabled) || false;
856856
this._setDisabled(disabled);
857857
}
858858

859859
/** Gets the slider thumb input of the given thumb position. */
860860
_getInput(thumbPosition: Thumb): MatSliderThumb {
861-
return thumbPosition === Thumb.END ? this._inputs.last! : this._inputs.first!;
861+
return thumbPosition === Thumb.END ? this._inputs?.last! : this._inputs?.first!;
862862
}
863863

864864
/** Gets the slider thumb HTML input element of the given thumb position. */
865865
_getInputElement(thumbPosition: Thumb): HTMLInputElement {
866-
return this._getInput(thumbPosition)._hostElement;
866+
return this._getInput(thumbPosition)?._hostElement;
867867
}
868868

869869
_getThumb(thumbPosition: Thumb): MatSliderVisualThumb {
870-
return thumbPosition === Thumb.END ? this._thumbs.last! : this._thumbs.first!;
870+
return thumbPosition === Thumb.END ? this._thumbs?.last! : this._thumbs?.first!;
871871
}
872872

873873
/** Gets the slider thumb HTML element of the given thumb position. */
874874
_getThumbElement(thumbPosition: Thumb): HTMLElement {
875-
return this._getThumb(thumbPosition)._getHostElement();
875+
return this._getThumb(thumbPosition)?._getHostElement();
876876
}
877877

878878
/** Gets the slider knob HTML element of the given thumb position. */
879879
_getKnobElement(thumbPosition: Thumb): HTMLElement {
880-
return this._getThumb(thumbPosition)._getKnob();
880+
return this._getThumb(thumbPosition)?._getKnob();
881881
}
882882

883883
/**
@@ -1167,7 +1167,7 @@ class SliderAdapter implements MDCSliderAdapter {
11671167
evtType: K,
11681168
handler: SpecificEventListener<K>,
11691169
): void => {
1170-
this._delegate._getThumbElement(thumbPosition).removeEventListener(evtType, handler);
1170+
this._delegate._getThumbElement(thumbPosition)?.removeEventListener(evtType, handler);
11711171
};
11721172
registerInputEventHandler = <K extends EventType>(
11731173
thumbPosition: Thumb,
@@ -1177,7 +1177,7 @@ class SliderAdapter implements MDCSliderAdapter {
11771177
if (evtType === 'change') {
11781178
this._saveChangeEventHandler(thumbPosition, handler as SpecificEventListener<EventType>);
11791179
} else {
1180-
this._delegate._getInputElement(thumbPosition).addEventListener(evtType, handler);
1180+
this._delegate._getInputElement(thumbPosition)?.addEventListener(evtType, handler);
11811181
}
11821182
};
11831183
deregisterInputEventHandler = <K extends EventType>(
@@ -1188,7 +1188,7 @@ class SliderAdapter implements MDCSliderAdapter {
11881188
if (evtType === 'change') {
11891189
this._globalEventSubscriptions.unsubscribe();
11901190
} else {
1191-
this._delegate._getInputElement(thumbPosition).removeEventListener(evtType, handler);
1191+
this._delegate._getInputElement(thumbPosition)?.removeEventListener(evtType, handler);
11921192
}
11931193
};
11941194
registerBodyEventHandler = <K extends EventType>(

0 commit comments

Comments
 (0)