Skip to content

Commit f067ee9

Browse files
committed
fix(table): unable to sort large numbers in strings
Fixes not being able to sort numbers, inside strings, that are greater than the `MAX_SAFE_INTEGER`. These changes treat these numbers as strings since JS can't compare them reliably. Fixes #12009.
1 parent c40fef4 commit f067ee9

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/lib/table/table-data-source.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,16 @@ export class MatTableDataSource<T> extends DataSource<T> {
104104
sortingDataAccessor: ((data: T, sortHeaderId: string) => string|number) =
105105
(data: T, sortHeaderId: string): string|number => {
106106
const value: any = data[sortHeaderId];
107-
return _isNumberValue(value) ? Number(value) : value;
107+
108+
if (_isNumberValue(value)) {
109+
const numberValue = Number(value);
110+
111+
// Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we
112+
// leave them as strings. For more info: https://goo.gl/y5vbSg
113+
return numberValue < Number.MAX_SAFE_INTEGER ? numberValue : value;
114+
}
115+
116+
return value;
108117
}
109118

110119
/**

src/lib/table/table.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,38 @@ describe('MatTable', () => {
400400
['Footer A', 'Footer B', 'Footer C'],
401401
]);
402402
}));
403+
404+
it('should sort strings with numbers larger than MAX_SAFE_INTEGER correctly', () => {
405+
const large = '9563256840123535';
406+
const larger = '9563256840123536';
407+
const largest = '9563256840123537';
408+
409+
dataSource.data[0].a = largest;
410+
dataSource.data[1].a = larger;
411+
dataSource.data[2].a = large;
412+
413+
component.sort.sort(component.sortHeader);
414+
fixture.detectChanges();
415+
expectTableToMatchContent(tableElement, [
416+
['Column A', 'Column B', 'Column C'],
417+
[large, 'b_3', 'c_3'],
418+
[larger, 'b_2', 'c_2'],
419+
[largest, 'b_1', 'c_1'],
420+
['Footer A', 'Footer B', 'Footer C'],
421+
]);
422+
423+
424+
component.sort.sort(component.sortHeader);
425+
fixture.detectChanges();
426+
expectTableToMatchContent(tableElement, [
427+
['Column A', 'Column B', 'Column C'],
428+
[largest, 'b_1', 'c_1'],
429+
[larger, 'b_2', 'c_2'],
430+
[large, 'b_3', 'c_3'],
431+
['Footer A', 'Footer B', 'Footer C'],
432+
]);
433+
});
434+
403435
});
404436
});
405437

0 commit comments

Comments
 (0)