Skip to content

Commit 372549c

Browse files
crisbetommalerba
authored andcommitted
fix(select): throwing additional errors if ngModel fails to initialize (#5405)
If the user has an `md-select` with an `ngModel` that doesn't have a name inside a form, the forms module will throw an error, however Material will also start throwing errors, which may cause confusion. These changes add a null check so our errors don't get mixed up with the forms error. Fixes #5402.
1 parent b7efe48 commit 372549c

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

src/lib/select/select.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
#trigger>
88
<span
99
class="mat-select-placeholder"
10-
[class.mat-floating-placeholder]="_selectionModel.hasValue()"
10+
[class.mat-floating-placeholder]="_hasValue()"
1111
[@transformPlaceholder]="_getPlaceholderAnimationState()"
1212
[style.opacity]="_getPlaceholderOpacity()"
1313
[style.width.px]="_selectedValueWidth"> {{ placeholder }} </span>
14-
<span class="mat-select-value" *ngIf="_selectionModel.hasValue()">
14+
<span class="mat-select-value" *ngIf="_hasValue()">
1515
<span class="mat-select-value-text">{{ triggerValue }}</span>
1616
</span>
1717

src/lib/select/select.spec.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ describe('MdSelect', () => {
6262
BasicSelectWithTheming,
6363
ResetValuesSelect,
6464
FalsyValueSelect,
65-
SelectWithGroups
65+
SelectWithGroups,
66+
InvalidSelectInForm
6667
],
6768
providers: [
6869
{provide: OverlayContainer, useFactory: () => {
@@ -1972,6 +1973,17 @@ describe('MdSelect', () => {
19721973
}).not.toThrow();
19731974
}));
19741975

1976+
it('should not throw selection model-related errors in addition to the errors from ngModel',
1977+
async(() => {
1978+
const fixture = TestBed.createComponent(InvalidSelectInForm);
1979+
1980+
// The first change detection run will throw the "ngModel is missing a name" error.
1981+
expect(() => fixture.detectChanges()).toThrowError(/the name attribute must be set/g);
1982+
1983+
// The second run shouldn't throw selection-model related errors.
1984+
expect(() => fixture.detectChanges()).not.toThrow();
1985+
}));
1986+
19751987
});
19761988

19771989
describe('change event', () => {
@@ -2872,3 +2884,11 @@ class SelectWithGroups {
28722884
@ViewChild(MdSelect) select: MdSelect;
28732885
@ViewChildren(MdOption) options: QueryList<MdOption>;
28742886
}
2887+
2888+
2889+
@Component({
2890+
template: `<form><md-select [(ngModel)]="value"></md-select></form>`
2891+
})
2892+
class InvalidSelectInForm {
2893+
value: any;
2894+
}

src/lib/select/select.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
548548
this._setScrollTop();
549549
}
550550

551+
/** Whether the select has a value. */
552+
_hasValue(): boolean {
553+
return this._selectionModel && this._selectionModel.hasValue();
554+
}
555+
551556
/**
552557
* Sets the scroll position of the scroll container. This must be called after
553558
* the overlay pane is attached or the scroll container element will not yet be
@@ -772,7 +777,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
772777
// The farthest the panel can be scrolled before it hits the bottom
773778
const maxScroll = scrollContainerHeight - panelHeight;
774779

775-
if (this._selectionModel.hasValue()) {
780+
if (this._hasValue()) {
776781
let selectedOptionOffset = this._getOptionIndex(this._selectionModel.selected[0])!;
777782

778783
selectedOptionOffset += this._getLabelCountBeforeOption(selectedOptionOffset);

0 commit comments

Comments
 (0)