angularangular-materialangular-material2angular-datatablesangular-cdk

Angular Material Table Error: Can't bind to 'mdHeaderRowDef' since it isn't a known property of 'md-header-row'


I'm trying to convert a CDK data-table to a Material Design styled data-table (see: https://material.angular.io/components/table/overview), but when I change the cdk prefixes to md, I get the following error...


Uncaught Error: Template parse errors: Can't bind to 'mdHeaderRowDef' since it isn't a known property of 'md-header-row'. 1. If 'md-header-row' is an Angular component and it has 'mdHeaderRowDef' input, then verify that it is part of this module. 2. If 'md-header-row' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. 3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.


Every answer I've found online tells me that I need to import CdkTableModule, but I have done so & cdk tables work perfectly.

import {Component, OnInit, ViewChild} from '@angular/core';
import {DataSource} from '@angular/cdk';
import { CdkTableModule } from '@angular/cdk';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';

I am importing CdkTableModule, and when I use the cdk prefix, the table displays as expected...

<md-table [dataSource]="dataSource">

  <ng-container cdkColumnDef="number">
    <md-header-cell *cdkHeaderCellDef> number </md-header-cell>
    <md-cell *cdkCellDef="let element"><a routerLink="{{element.number}}"> {{element.number}} </a></md-cell>
  </ng-container>

  <ng-container cdkColumnDef="book">
    <md-header-cell *cdkHeaderCellDef> book </md-header-cell>
    <md-cell *cdkCellDef="let element"> {{element.book}} </md-cell>
  </ng-container>

  <md-header-row *cdkHeaderRowDef="['number', 'book']"></md-header-row>
  <md-row *cdkRowDef="let row; columns: ['number', 'book']"></md-row>
</md-table>

RESULT: So far so good... enter image description here but if i change "cdk" to "md"

<md-table [dataSource]="dataSource">

  <ng-container mdColumnDef="number">
    <md-header-cell *mdHeaderCellDef> number </md-header-cell>
    <md-cell *mdCellDef="let element"><a routerLink="{{element.number}}"> {{element.number}} </a></md-cell>
  </ng-container>

  <ng-container mdColumnDef="book">
    <md-header-cell *mdHeaderCellDef> book </md-header-cell>
    <md-cell *mdCellDef="let element"> {{element.book}} </md-cell>
  </ng-container>

  <md-header-row *mdHeaderRowDef="['number', 'book']"></md-header-row>
  <md-row *mdRowDef="let row; columns: ['number', 'book']"></md-row>
</md-table>

RESULT: Broken :( enter image description here

I've tried importing other modules... including MdTableModule & MdTable, but that hasn't proven helpful either. Any ideas?

P.S. Here's my main app.module.ts import statement in case that helps

imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule,
ReactiveFormsModule,
BrowserAnimationsModule,
MdAutocompleteModule,
MdButtonModule,
MdButtonToggleModule,
MdCardModule,
MdCheckboxModule,
MdChipsModule,
MdTableModule,
MdDatepickerModule,
MdDialogModule,
MdExpansionModule,
MdGridListModule,
MdIconModule,
MdInputModule,
MdListModule,
MdMenuModule,
MdCoreModule,
MdPaginatorModule,
MdProgressBarModule,
MdProgressSpinnerModule,
MdRadioModule,
MdRippleModule,
MdSelectModule,
MdSidenavModule,
MdSlideToggleModule,
MdSliderModule,
MdSnackBarModule,
MdSortModule,
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
MdNativeDateModule,
CdkTableModule,
StyleModule
 ]

Solution

  • After another hour of fiddling with things, I ran

    npm update --save

    and updated @angular/cdk and @angular/material to 2.0.0-beta.10

    in package.json

     "@angular/material": "^2.0.0-beta.10",
     "@angular/cdk": "^2.0.0-beta.10",
    

    This broke some things, so I had to dig around and needed to update imports of DataSource and CdkTableModule

           import { CdkTableModule} from '@angular/cdk/table';
           import {DataSource} from '@angular/cdk/table';
    

    component.html

     <md-table [dataSource]="dataSource">
    
        <ng-container mdColumnDef="number">
          <md-header-cell *mdHeaderCellDef> number </md-header-cell>
          <md-cell *mdCellDef="let element"><a routerLink="{{element.number}}"> {{element.number}} </a></md-cell>
        </ng-container>
    
        <ng-container mdColumnDef="book">
          <md-header-cell *mdHeaderCellDef> book </md-header-cell>
          <md-cell *mdCellDef="let element"> {{element.book}} </md-cell>
        </ng-container>
    
        <ng-container mdColumnDef="s1">
          <md-header-cell *mdHeaderCellDef> S1 </md-header-cell>
          <md-cell *mdCellDef="let element"> {{element.sections[0] ? element.sections[0].type : ''}} {{element.sections[0] && element.sections[0].qs ? '('+element.sections[0].qs.length+')' : ''}}</md-cell>
        </ng-container>
    
        <ng-container mdColumnDef="s2">
          <md-header-cell *mdHeaderCellDef> S2 </md-header-cell>
          <md-cell *mdCellDef="let element"> {{element.sections[1] ? element.sections[1].type : ''}} {{element.sections[1] && element.sections[1].qs  ? '('+element.sections[1].qs.length+')' : ''}} </md-cell>
        </ng-container>
    
        <ng-container mdColumnDef="s3">
          <md-header-cell *mdHeaderCellDef> S3 </md-header-cell>
          <md-cell *mdCellDef="let element"> {{element.sections[2] ? element.sections[2].type : ''}} {{element.sections[2] && element.sections[2].qs ? '('+element.sections[2].qs.length+')' : ''}}</md-cell>
        </ng-container>
    
        <ng-container mdColumnDef="s4">
          <md-header-cell *mdHeaderCellDef> S4 </md-header-cell>
          <md-cell *mdCellDef="let element"> {{element.sections[3] ? element.sections[3].type : ''}} {{element.sections[3] && element.sections[3].qs ? '('+element.sections[3].qs.length+')' : ''}}</md-cell>
        </ng-container>
    
        <md-header-row *mdHeaderRowDef="['number', 'book', 's1', 's2', 's3', 's4']"></md-header-row>
        <md-row *mdRowDef="let row; columns: ['number', 'book', 's1', 's2', 's3', 's4']"></md-row>
      </md-table>
    

    component.ts

     import {Component, OnInit} from '@angular/core';
    
     // Data Table imports.
         import { DataSource } from '@angular/cdk/table';
         import { Observable } from 'rxjs/Observable';
         import 'rxjs/add/observable/of';
    
     @Component({
       selector: 'app-start',
       templateUrl: './start.component.html',
       styleUrls: ['./start.component.css']
     })
     export class StartComponent implements OnInit {
    
       pts: Pt[];
       dataSource = new ExampleDataSource(this.ptService);
       constructor( public ptService: PtService ) { }
       ngOnInit() {
         this.pt = this.ptService.getPts();
       }
     }
    
     export class ExampleDataSource extends DataSource<any> {
       data = this.ptService.getPts();
       constructor( public ptService: PtService ) { super() }
       /** Connect function called by the table to retrieve one stream containing the data to render. */
       connect(): Observable<Pt[]> {
         return Observable.of(this.data);
       }
       disconnect() {}
     }
    

    Phew!