Skip to content

Commit e82457c

Browse files
crisbetotinayuangao
authored andcommitted
fix(select): exception if selected value is accessed on init (#3785)
Fixes an error that is thrown if something attempts to access the `selected` value of `md-select` too early. The issue comes from the fact that the underlying `SelectionModel` gets initialized too late in `ngAfterContentInit`. Fixes #3750.
1 parent 4282917 commit e82457c

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/lib/select/select.spec.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ describe('MdSelect', () => {
4646
ThrowsErrorOnInit,
4747
BasicSelectOnPush,
4848
BasicSelectOnPushPreselected,
49-
SelectWithPlainTabindex
49+
SelectWithPlainTabindex,
50+
SelectEarlyAccessSibling
5051
],
5152
providers: [
5253
{provide: OverlayContainer, useFactory: () => {
@@ -1337,6 +1338,12 @@ describe('MdSelect', () => {
13371338
}).toThrowError(new RegExp('Oh no!', 'g'));
13381339
}));
13391340

1341+
it('should not throw when trying to access the selected value on init', async(() => {
1342+
expect(() => {
1343+
TestBed.createComponent(SelectEarlyAccessSibling).detectChanges();
1344+
}).not.toThrow();
1345+
}));
1346+
13401347
});
13411348

13421349
describe('change event', () => {
@@ -1941,6 +1948,15 @@ class MultiSelect {
19411948
})
19421949
class SelectWithPlainTabindex { }
19431950

1951+
@Component({
1952+
selector: 'select-early-sibling-access',
1953+
template: `
1954+
<md-select #select="mdSelect"></md-select>
1955+
<div *ngIf="select.selected"></div>
1956+
`
1957+
})
1958+
class SelectEarlyAccessSibling { }
1959+
19441960

19451961
class FakeViewportRuler {
19461962
getViewportRect() {

src/lib/select/select.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ViewChild,
1616
ChangeDetectorRef,
1717
Attribute,
18+
OnInit,
1819
} from '@angular/core';
1920
import {MdOption, MdOptionSelectionChange} from '../core/option/option';
2021
import {ENTER, SPACE} from '../core/keyboard/keycodes';
@@ -119,7 +120,7 @@ export type MdSelectFloatPlaceholderType = 'always' | 'never' | 'auto';
119120
],
120121
exportAs: 'mdSelect',
121122
})
122-
export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestroy {
123+
export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlValueAccessor {
123124
/** Whether or not the overlay panel is open. */
124125
private _panelOpen = false;
125126

@@ -311,8 +312,11 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
311312
this._tabIndex = parseInt(tabIndex) || 0;
312313
}
313314

314-
ngAfterContentInit() {
315+
ngOnInit() {
315316
this._selectionModel = new SelectionModel<MdOption>(this.multiple, null, false);
317+
}
318+
319+
ngAfterContentInit() {
316320
this._initKeyManager();
317321

318322
this._changeSubscription = this.options.changes.startWith(null).subscribe(() => {

0 commit comments

Comments
 (0)