Skip to content

Commit a41ac2b

Browse files
authored
fix(material/select): error if selected value is accessed too early (#23378)
Fixes that the select throws if the `selected` value is accessed before everything is initialized. Fixes #23371.
1 parent 530febe commit a41ac2b

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
@@ -2703,11 +2703,34 @@ expect(panel.scrollTop)
27032703
describe(`when the select's value is accessed on initialization`, () => {
27042704
beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectEarlyAccessSibling])));
27052705

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

27132736
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
@@ -2770,11 +2770,34 @@ describe('MatSelect', () => {
27702770
describe(`when the select's value is accessed on initialization`, () => {
27712771
beforeEach(waitForAsync(() => configureMatSelectTestingModule([SelectEarlyAccessSibling])));
27722772

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

27802803
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)