Skip to content

Commit

Permalink
fix(material/select): fix recursive call to SelectionModel.select() (#…
Browse files Browse the repository at this point in the history
…17071)

Checks if option selection state in SelectionModel is different than the option selected value. Fixes "Maximum call stack size exceeded" error.

(cherry picked from commit 14cdd89)
  • Loading branch information
ogix authored and jelbourn committed Sep 24, 2019
1 parent 0e5c82c commit ed96878
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
39 changes: 38 additions & 1 deletion src/material/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3905,7 +3905,10 @@ describe('MatSelect', () => {
});

describe('with multiple selection', () => {
beforeEach(async(() => configureMatSelectTestingModule([MultiSelect])));
beforeEach(async(() => configureMatSelectTestingModule([
MultiSelect,
MultiSelectWithLotsOfOptions
])));

let fixture: ComponentFixture<MultiSelect>;
let testInstance: MultiSelect;
Expand Down Expand Up @@ -4286,6 +4289,18 @@ describe('MatSelect', () => {
expect(testInstance.control.value).toEqual([]);
});

it('should not throw when selecting a large amount of options', fakeAsync(() => {
fixture.destroy();

const lotsOfOptionsFixture = TestBed.createComponent(MultiSelectWithLotsOfOptions);

expect(() => {
lotsOfOptionsFixture.componentInstance.checkAll();
lotsOfOptionsFixture.detectChanges();
flush();
}).not.toThrow();
}));

});
});

Expand Down Expand Up @@ -5062,3 +5077,25 @@ class SelectWithFormFieldLabel {
class SelectWithNgIfAndLabel {
showSelect = true;
}

@Component({
template: `
<mat-form-field>
<mat-select multiple [ngModel]="value">
<mat-option *ngFor="let item of items" [value]="item">{{item}}</mat-option>
</mat-select>
</mat-form-field>
`
})
class MultiSelectWithLotsOfOptions {
items = new Array(1000).fill(0).map((_, i) => i);
value: number[] = [];

checkAll() {
this.value = [...this.items];
}

uncheckAll() {
this.value = [];
}
}
5 changes: 4 additions & 1 deletion src/material/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
this._selectionModel.clear();
this._propagateChanges(option.value);
} else {
option.selected ? this._selectionModel.select(option) : this._selectionModel.deselect(option);
if (wasSelected !== option.selected) {
option.selected ? this._selectionModel.select(option) :
this._selectionModel.deselect(option);
}

if (isUserInput) {
this._keyManager.setActiveItem(option);
Expand Down

0 comments on commit ed96878

Please sign in to comment.