Is this a regression?
The previous version in which this bug was not present was
No response
Description
SelectionModel.setSelection(...values: T[]) is the only public API for replacing the whole selection in one call, but its rest-parameter signature means the caller must spread the array into the call. For large selections this exceeds the JavaScript engine's function-argument limit and throws:
RangeError: Maximum call stack size exceeded
There is no array-accepting alternative, so a "select all" over a large list (e.g. a virtual-scroll grid of 100k+ rows) has no working public path: setSelection(...all) crashes, and the per-item select() loop is O(n²) when a compareWith is configured (each _getConcreteValue linearly scans the growing set). This effectively makes bulk selection of large lists impossible without reaching into the private _selection field.
Additional context:
Reproduction
Steps: run the snippet (StackBlitz or node). The exact threshold is engine-dependent (Chrome/V8 throws well before Node does), so increase N if it doesn't trip immediately.
StackBlitz
import { SelectionModel } from '@angular/cdk/collections';
const N = 2_000_000; // raise if your engine tolerates this count
const items = Array.from({ length: N }, (_, i) => i);
const model = new SelectionModel<number>(true);
// Works (but O(n²) when a compareWith is supplied):
items.forEach(i => model.select(i));
console.log('incremental select ok:', model.selected.length);
model.clear();
// The only public *bulk* API — throws on large arrays:
model.setSelection(...items); // RangeError: Maximum call stack size exceeded
console.log('setSelection ok:', model.selected.length); // never reached
Expected Behavior
Replacing the selection with a large array should succeed (or at least not crash). Either:
- setSelection iterates internally instead of spreading, or
- an array-accepting overload/method is provided, e.g. setSelection(values: T[]) / replaceSelection(values: readonly T[]).
Actual Behavior
setSelection(...largeArray) throws RangeError: Maximum call stack size exceeded. There is no non-crashing public way to bulk-replace a large selection.
Environment
- @angular/cdk: 20.2.x (signature unchanged on main)
- Browser: Chrome (V8)
Is this a regression?
The previous version in which this bug was not present was
No response
Description
SelectionModel.setSelection(...values: T[]) is the only public API for replacing the whole selection in one call, but its rest-parameter signature means the caller must spread the array into the call. For large selections this exceeds the JavaScript engine's function-argument limit and throws:
RangeError: Maximum call stack size exceededThere is no array-accepting alternative, so a "select all" over a large list (e.g. a virtual-scroll grid of 100k+ rows) has no working public path: setSelection(...all) crashes, and the per-item select() loop is O(n²) when a compareWith is configured (each _getConcreteValue linearly scans the growing set). This effectively makes bulk selection of large lists impossible without reaching into the private _selection field.
Additional context:
also resolve it.
Reproduction
Steps: run the snippet (StackBlitz or node). The exact threshold is engine-dependent (Chrome/V8 throws well before Node does), so increase N if it doesn't trip immediately.
StackBlitz
Expected Behavior
Replacing the selection with a large array should succeed (or at least not crash). Either:
Actual Behavior
setSelection(...largeArray) throws RangeError: Maximum call stack size exceeded. There is no non-crashing public way to bulk-replace a large selection.
Environment