From 615ef550b21551d7e4826bc9ea05310f5691c1be Mon Sep 17 00:00:00 2001 From: Nathan Clarke Date: Thu, 24 Jan 2019 12:16:36 -0700 Subject: [PATCH] fix(table): Clarify unknown table column error Throwing error when column not found in _addStickyColumnStyles to avoid weird error of "Cannot read property 'sticky' of undefined". --- src/cdk/table/table.spec.ts | 36 +++++++++++++++++++++++++++++++++++- src/cdk/table/table.ts | 8 +++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/cdk/table/table.spec.ts b/src/cdk/table/table.spec.ts index 7bab50b5a2a6..8789b823b1bc 100644 --- a/src/cdk/table/table.spec.ts +++ b/src/cdk/table/table.spec.ts @@ -7,7 +7,8 @@ import { Input, QueryList, Type, - ViewChild + ViewChild, + AfterViewInit } from '@angular/core'; import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing'; import {BehaviorSubject, combineLatest, Observable, of as observableOf} from 'rxjs'; @@ -528,6 +529,17 @@ describe('CdkTable', () => { .toThrowError(getTableUnknownColumnError('column_a').message); }); + it('should throw an error if a column definition is requested but not defined after render', + fakeAsync(() => { + const columnDefinitionMissingAfterRenderFixture = + createComponent(MissingColumnDefAfterRenderCdkTableApp); + expect(() => { + columnDefinitionMissingAfterRenderFixture.detectChanges(); + flush(); + columnDefinitionMissingAfterRenderFixture.detectChanges(); + }).toThrowError(getTableUnknownColumnError('column_a').message); + })); + it('should throw an error if the row definitions are missing', () => { expect(() => createComponent(MissingAllRowDefsCdkTableApp).detectChanges()) .toThrowError(getTableMissingRowDefsError().message); @@ -1964,6 +1976,28 @@ class MissingColumnDefCdkTableApp { dataSource: FakeDataSource = new FakeDataSource(); } +@Component({ + template: ` + + + Column A + {{row.a}} + + + + + + ` +}) +class MissingColumnDefAfterRenderCdkTableApp implements AfterViewInit { + dataSource: FakeDataSource|null = null; + displayedColumns: string[] = []; + + ngAfterViewInit() { + setTimeout(() => { this.displayedColumns = ['column_a']; }, 0); + } +} + @Component({ template: ` diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 4919071119b9..89f2e9badf15 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -851,7 +851,13 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes /** Adds the sticky column styles for the rows according to the columns' stick states. */ private _addStickyColumnStyles(rows: HTMLElement[], rowDef: BaseRowDef) { - const columnDefs = Array.from(rowDef.columns || []).map(c => this._columnDefsByName.get(c)!); + const columnDefs = Array.from(rowDef.columns || []).map(columnName => { + const columnDef = this._columnDefsByName.get(columnName); + if (!columnDef) { + throw getTableUnknownColumnError(columnName); + } + return columnDef!; + }); const stickyStartStates = columnDefs.map(columnDef => columnDef.sticky); const stickyEndStates = columnDefs.map(columnDef => columnDef.stickyEnd); this._stickyStyler.updateStickyColumns(rows, stickyStartStates, stickyEndStates);