Skip to content

Commit adda21f

Browse files
crisbetojosephperrott
authored andcommitted
fix(table): unable to sort large numbers in strings (#12052)
1 parent 5b72ec7 commit adda21f

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import {MatPaginator, PageEvent} from '@angular/material/paginator';
2020
import {MatSort, Sort} from '@angular/material/sort';
2121
import {map} from 'rxjs/operators';
2222

23+
/**
24+
* Corresponds to `Number.MAX_SAFE_INTEGER`. Moved out into a variable here due to
25+
* flaky browser support and the value not being defined in Closure's typings.
26+
*/
27+
const MAX_SAFE_INTEGER = 9007199254740991;
2328

2429
/**
2530
* Data source that accepts a client-side data array and includes native support of filtering,
@@ -104,7 +109,16 @@ export class MatTableDataSource<T> extends DataSource<T> {
104109
sortingDataAccessor: ((data: T, sortHeaderId: string) => string|number) =
105110
(data: T, sortHeaderId: string): string|number => {
106111
const value: any = data[sortHeaderId];
107-
return _isNumberValue(value) ? Number(value) : value;
112+
113+
if (_isNumberValue(value)) {
114+
const numberValue = Number(value);
115+
116+
// Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we
117+
// leave them as strings. For more info: https://goo.gl/y5vbSg
118+
return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
119+
}
120+
121+
return value;
108122
}
109123

110124
/**

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)