From 712830b026a63386d095f58d8489c25cb2e51b14 Mon Sep 17 00:00:00 2001 From: Jeremias Peier Date: Mon, 17 Jan 2022 09:09:06 +0100 Subject: [PATCH] fix(angular/table): better handling of invalid data The table data source is set up to expect an array and will throw a cryptic error down the line if the value is anything different. While typings should be enough to enforce this, if the value comes from somewhere in the view it may not get caught. Since the effort for handling it on our end is minimal, these changes add some logic that fall back to an empty array if the value is invalid. https://github.com/angular/components/pull/18953 --- src/angular/table/table.spec.ts | 39 ++++++++++++++++++++ src/angular/table/table/table-data-source.ts | 1 + 2 files changed, 40 insertions(+) diff --git a/src/angular/table/table.spec.ts b/src/angular/table/table.spec.ts index c8a8d25277..63d9cc7d8e 100644 --- a/src/angular/table/table.spec.ts +++ b/src/angular/table/table.spec.ts @@ -543,6 +543,45 @@ describe('SbbTable', () => { ['Footer A', 'Footer B', 'Footer C'], ]); }); + + it('should fall back to empty table if invalid data is passed in', () => { + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = null!; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['a_5', 'b_5', 'c_5'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = {} as any; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + }); }); it('should set css classes to grouped columns', () => { diff --git a/src/angular/table/table/table-data-source.ts b/src/angular/table/table/table-data-source.ts index 0a58f545eb..d19bdab0c3 100644 --- a/src/angular/table/table/table-data-source.ts +++ b/src/angular/table/table/table-data-source.ts @@ -80,6 +80,7 @@ export class _SbbTableDataSource< return this._data.value; } set data(data: T[]) { + data = Array.isArray(data) ? data : []; this._data.next(data); // Normally the `filteredData` is updated by the re-render // subscription, but that won't happen if it's inactive.