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

61.5k views Asked by At

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
 ]
4

There are 4 answers

1
Joshua Craven On BEST ANSWER

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!

0
Aneri Fumtiwala On

import MatTableModule in app.module.ts

import { MatTableModule } from '@angular/material/table';

@NgModule({
  imports: [
     MatTableModule
  ]
})
export class AppModule { }
0
user1610308 On

Since "^2.0.0-beta.11" all the selectors that start with md are not valid and should be replaced with mat so you have to replace all of them, in material website the documents do not seem to be updated yet.

0
Marcos Randulfe Garrido On

All types of tables have her own prefix if you use one type you have to use her prefix. It's clear like that