Skip to content

Commit 4083b10

Browse files
crisbetoannieyw
authored andcommitted
fix(select): not marking options as selected correctly when setting value with duplicates (#13361)
Fixes `mat-select` not marking all of the options as selected, when an array with duplicate values is assigned programmatically. Fixes #13179. (cherry picked from commit 07faecc)
1 parent 1c16d91 commit 4083b10

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/material/select/select.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4640,6 +4640,32 @@ describe('MatSelect', () => {
46404640
}).not.toThrow();
46414641
}));
46424642

4643+
it('should be able to programmatically set an array with duplicate values', fakeAsync(() => {
4644+
testInstance.foods = [
4645+
{ value: 'steak-0', viewValue: 'Steak' },
4646+
{ value: 'pizza-1', viewValue: 'Pizza' },
4647+
{ value: 'pizza-1', viewValue: 'Pizza' },
4648+
{ value: 'pizza-1', viewValue: 'Pizza' },
4649+
{ value: 'pizza-1', viewValue: 'Pizza' },
4650+
{ value: 'pizza-1', viewValue: 'Pizza' },
4651+
];
4652+
fixture.detectChanges();
4653+
testInstance.control.setValue(['steak-0', 'pizza-1', 'pizza-1', 'pizza-1']);
4654+
fixture.detectChanges();
4655+
4656+
trigger.click();
4657+
fixture.detectChanges();
4658+
4659+
const optionNodes = Array.from(overlayContainerElement.querySelectorAll('mat-option'));
4660+
const optionInstances = testInstance.options.toArray();
4661+
4662+
expect(optionNodes.map(node => node.classList.contains('mat-selected')))
4663+
.toEqual([true, true, true, true, false, false]);
4664+
4665+
expect(optionInstances.map(instance => instance.selected))
4666+
.toEqual([true, true, true, true, false, false]);
4667+
}));
4668+
46434669
});
46444670

46454671
it('should be able to provide default values through an injection token', fakeAsync(() => {

src/material/select/select.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,12 @@ export abstract class _MatSelectBase<C> extends _MatSelectMixinBase implements A
847847
*/
848848
private _selectValue(value: any): MatOption | undefined {
849849
const correspondingOption = this.options.find((option: MatOption) => {
850+
// Skip options that are already in the model. This allows us to handle cases
851+
// where the same primitive value is selected multiple times.
852+
if (this._selectionModel.isSelected(option)) {
853+
return false;
854+
}
855+
850856
try {
851857
// Treat null as a special reset value.
852858
return option.value != null && this._compareWith(option.value, value);

0 commit comments

Comments
 (0)