Skip to content

Commit 42152eb

Browse files
committed
fix(material/select): error if selected value is accessed too early
Fixes that the select throws if the `selected` value is accessed before everything is initialized. Fixes #23371.
1 parent 8424209 commit 42152eb

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,11 +2709,34 @@ expect(panel.scrollTop)
27092709
describe(`when the select's value is accessed on initialization`, () => {
27102710
beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectEarlyAccessSibling])));
27112711

2712-
it('should not throw when trying to access the selected value on init', fakeAsync(() => {
2713-
expect(() => {
2714-
TestBed.createComponent(SelectEarlyAccessSibling).detectChanges();
2715-
}).not.toThrow();
2716-
}));
2712+
it('should not throw when trying to access the selected value on init in the view',
2713+
fakeAsync(() => {
2714+
expect(() => {
2715+
TestBed.createComponent(SelectEarlyAccessSibling).detectChanges();
2716+
}).not.toThrow();
2717+
}));
2718+
2719+
it('should not throw when reading selected value programmatically in single selection mode',
2720+
fakeAsync(() => {
2721+
expect(() => {
2722+
const fixture = TestBed.createComponent(SelectEarlyAccessSibling);
2723+
const select = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;
2724+
// We're checking that accessing the getter won't throw.
2725+
select.multiple = false;
2726+
return select.selected;
2727+
}).not.toThrow();
2728+
}));
2729+
2730+
it('should not throw when reading selected value programmatically in multi selection mode',
2731+
fakeAsync(() => {
2732+
expect(() => {
2733+
const fixture = TestBed.createComponent(SelectEarlyAccessSibling);
2734+
const select = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;
2735+
// We're checking that accessing the getter won't throw.
2736+
select.multiple = true;
2737+
return select.selected;
2738+
}).not.toThrow();
2739+
}));
27172740
});
27182741

27192742
describe('with ngIf and mat-label', () => {

src/material/select/select.spec.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2776,11 +2776,34 @@ describe('MatSelect', () => {
27762776
describe(`when the select's value is accessed on initialization`, () => {
27772777
beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectEarlyAccessSibling])));
27782778

2779-
it('should not throw when trying to access the selected value on init', fakeAsync(() => {
2780-
expect(() => {
2781-
TestBed.createComponent(SelectEarlyAccessSibling).detectChanges();
2782-
}).not.toThrow();
2783-
}));
2779+
it('should not throw when trying to access the selected value on init in the view',
2780+
fakeAsync(() => {
2781+
expect(() => {
2782+
TestBed.createComponent(SelectEarlyAccessSibling).detectChanges();
2783+
}).not.toThrow();
2784+
}));
2785+
2786+
it('should not throw when reading selected value programmatically in single selection mode',
2787+
fakeAsync(() => {
2788+
expect(() => {
2789+
const fixture = TestBed.createComponent(SelectEarlyAccessSibling);
2790+
const select = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;
2791+
// We're checking that accessing the getter won't throw.
2792+
select.multiple = false;
2793+
return select.selected;
2794+
}).not.toThrow();
2795+
}));
2796+
2797+
it('should not throw when reading selected value programmatically in multi selection mode',
2798+
fakeAsync(() => {
2799+
expect(() => {
2800+
const fixture = TestBed.createComponent(SelectEarlyAccessSibling);
2801+
const select = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;
2802+
// We're checking that accessing the getter won't throw.
2803+
select.multiple = true;
2804+
return select.selected;
2805+
}).not.toThrow();
2806+
}));
27842807
});
27852808

27862809
describe('with ngIf and mat-label', () => {

src/material/select/select.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
624624

625625
/** The currently selected option. */
626626
get selected(): MatOption | MatOption[] {
627-
return this.multiple ? this._selectionModel.selected : this._selectionModel.selected[0];
627+
return this.multiple ? (this._selectionModel?.selected || []) :
628+
this._selectionModel?.selected[0];
628629
}
629630

630631
/** The value displayed in the trigger. */

0 commit comments

Comments
 (0)