Skip to content

Commit d55aa0c

Browse files
crisbetoandrewseguin
authored andcommitted
fix(select): unable to preselect array value in single selection mode (#7603)
Fixes not being able to preselect an array if a select is in single selection mode due to an assumption that an array value means that we're in mutliple selection mode. Fixes #7584.
1 parent c12e4b5 commit d55aa0c

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

src/lib/select/select.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ describe('MatSelect', () => {
105105
SelectInsideFormGroup,
106106
NgModelCompareWithSelect,
107107
CustomErrorBehaviorSelect,
108+
SingleSelectWithPreselectedArrayValues,
108109
],
109110
providers: [
110111
{provide: OverlayContainer, useFactory: () => {
@@ -1010,6 +1011,19 @@ describe('MatSelect', () => {
10101011
});
10111012
});
10121013
}));
1014+
1015+
it('should be able to preselect an array value in single-selection mode', fakeAsync(() => {
1016+
const fixture = TestBed.createComponent(SingleSelectWithPreselectedArrayValues);
1017+
fixture.detectChanges();
1018+
tick();
1019+
fixture.detectChanges();
1020+
1021+
const trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
1022+
1023+
expect(trigger.textContent).toContain('Pizza');
1024+
expect(fixture.componentInstance.options.toArray()[1].selected).toBe(true);
1025+
}));
1026+
10131027
});
10141028

10151029
describe('misc forms', () => {
@@ -3872,3 +3886,28 @@ class CustomErrorBehaviorSelect {
38723886
];
38733887
errorStateMatcher: ErrorStateMatcher;
38743888
}
3889+
3890+
3891+
@Component({
3892+
template: `
3893+
<mat-form-field>
3894+
<mat-select placeholder="Food" [(ngModel)]="selectedFoods">
3895+
<mat-option *ngFor="let food of foods"
3896+
[value]="food.value">{{ food.viewValue }}
3897+
</mat-option>
3898+
</mat-select>
3899+
</mat-form-field>
3900+
`
3901+
})
3902+
class SingleSelectWithPreselectedArrayValues {
3903+
foods: any[] = [
3904+
{ value: ['steak-0', 'steak-1'], viewValue: 'Steak' },
3905+
{ value: ['pizza-1', 'pizza-2'], viewValue: 'Pizza' },
3906+
{ value: ['tacos-2', 'tacos-3'], viewValue: 'Tacos' },
3907+
];
3908+
3909+
selectedFoods = this.foods[1].value;
3910+
3911+
@ViewChild(MatSelect) select: MatSelect;
3912+
@ViewChildren(MatOption) options: QueryList<MatOption>;
3913+
}

src/lib/select/select.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -700,18 +700,17 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
700700
* found with the designated value, the select trigger is cleared.
701701
*/
702702
private _setSelectionByValue(value: any | any[], isUserInput = false): void {
703-
const isArray = Array.isArray(value);
704-
705-
if (this.multiple && value && !isArray) {
706-
throw getMatSelectNonArrayValueError();
707-
}
708-
709-
this._clearSelection();
703+
if (this.multiple && value) {
704+
if (!Array.isArray(value)) {
705+
throw getMatSelectNonArrayValueError();
706+
}
710707

711-
if (isArray) {
708+
this._clearSelection();
712709
value.forEach((currentValue: any) => this._selectValue(currentValue, isUserInput));
713710
this._sortValues();
714711
} else {
712+
this._clearSelection();
713+
715714
const correspondingOption = this._selectValue(value, isUserInput);
716715

717716
// Shift focus to the active item. Note that we shouldn't do this in multiple
@@ -844,10 +843,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
844843
private _propagateChanges(fallbackValue?: any): void {
845844
let valueToEmit: any = null;
846845

847-
if (Array.isArray(this.selected)) {
848-
valueToEmit = this.selected.map(option => option.value);
846+
if (this.multiple) {
847+
valueToEmit = (this.selected as MatOption[]).map(option => option.value);
849848
} else {
850-
valueToEmit = this.selected ? this.selected.value : fallbackValue;
849+
valueToEmit = this.selected ? (this.selected as MatOption).value : fallbackValue;
851850
}
852851

853852
this._value = valueToEmit;

0 commit comments

Comments
 (0)