Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: cdk-table: Could not find column with id. Angular 2 Material Data Tables

So I'm following the documentation of angular 2 material DataTables. At first it was working with the providing codes at the documentation. However I changed the code a bit so that if I'm going to provide the actual data it will not be as hard as following the documentation of the angular material because I'm already used to it. So inject all the imports to my TS File

import { Component, OnInit, ViewChild } from '@angular/core';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/of';

all the imports needed for the angular data tables are imported. CdkTableModule is also imported at my materialModule

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

@NgModule({
  imports: [ 
    CdkTableModule,
    ..... as so on..
  ],
  exports: [ 
    CdkTableModule,
    ..... as so on..
  ]
}) export class MaterialModule { }

I'm going to show the important codes that are need to datatables

export class ManageGaragesComponent implements OnInit {
  displayedColumns = ['Garage Name', 'Address', 'Status', 'Slots'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ManageGarageDataSource | null;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  ngOnInit() {

    this.dataSource = new ManageGarageDataSource(this.exampleDatabase, this.paginator);  
  }
}



 export interface UserData {
  garageName: string;
  address: string;
  status: number;
  slots: number;
}



 /** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  get data(): UserData[] { 

    let garage_Data = [
      {garageName: '1 Ortigas Ave', address: 'Hydrogen', status: 1.0079, slots: 5},
      {garageName: '2 Ortigas Ave', address: 'Helium', status: 4.0026, slots: 6},
      {garageName: '3 Ortigas Ave', address: 'Lithium', status: 6.941, slots: 1},
      {garageName: '4 Ortigas Ave', address: 'Beryllium', status: 9.0122, slots: 1},
      {garageName: '5 Ortigas Ave', address: 'Boron', status: 10.811, slots: 1},
      {garageName: '6 Ortigas Ave', address: 'Carbon', status: 12.0107, slots: 1},
      {garageName: '7 Ortigas Ave', address: 'Nitrogen', status: 14.0067, slots: 2},
      {garageName: '8 Ortigas Ave', address: 'Oxygen', status: 15.9994, slots: 3},
      {garageName: '9 Ortigas Ave', address: 'Fluorine', status: 18.9984, slots: 4},
      {garageName: '10 Ortigas Ave', address: 'Neon', status: 20.1797, slots: 5},
      {garageName: '11 Ortigas Ave', address: 'Sodium', status: 22.9897, slots: 6},
      {garageName: '12 Ortigas Ave', address: 'Magnesium', status: 24.305, slots: 6},
      {garageName: '13 Ortigas Ave', address: 'Aluminum', status: 26.9815, slots: 6},
      {garageName: '14 Ortigas Ave', address: 'Silicon', status: 28.0855, slots: 8},
      {garageName: '15 Ortigas Ave', address: 'Phosphorus', status: 30.9738, slots: 8},
      {garageName: '16 Ortigas Ave', address: 'Sulfur', status: 32.065, slots: 2},
      {garageName: '17 Ortigas Ave', address: 'Chlorine', status: 35.453, slots: 6},
      {garageName: '18 Ortigas Ave', address: 'Argon', status: 39.948, slots: 8},
      {garageName: '19 Ortigas Ave', address: 'Potassium', status: 39.0983, slots: 6},
      {garageName: '20 Ortigas Ave', address: 'Calcium', status: 40.078, slots: 1},
    ];

    return garage_Data;
  }

  constructor() {
    this.dataChange.next(this.data);
  }
}


export class ManageGarageDataSource extends DataSource<any> {
  constructor(private _exampleDatabase: ExampleDatabase, private _paginator: MatPaginator) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._paginator.page,
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      const data = this._exampleDatabase.data.slice();
      console.log(data);
      // Grab the page's slice of data.
      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      return data.splice(startIndex, this._paginator.pageSize);
    });
  }

  disconnect() {}
}

so that is my ts codes. also my html

<mat-table #table [dataSource]="dataSource">

  <!--- Note that these columns can be defined in any order.
        The actual rendered columns are set as a property on the row definition" -->

  <!-- garage name Column -->
  <ng-container matColumnDef="garageName">
    <mat-header-cell *matHeaderCellDef> Garage Name </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.garageName}} </mat-cell>
  </ng-container>

  <!-- address Column -->
  <ng-container matColumnDef="address">
    <mat-header-cell *matHeaderCellDef> Address </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.address}}% </mat-cell>
  </ng-container>

  <!-- status Column -->
  <ng-container matColumnDef="status">
    <mat-header-cell *matHeaderCellDef> Status </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.status}} </mat-cell>
  </ng-container>

  <!-- slots Column -->
  <ng-container matColumnDef="slots">
    <mat-header-cell *matHeaderCellDef> Slots </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.slots}} </mat-cell>
  </ng-container>

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

<mat-paginator #paginator
               [length]="exampleDatabase.data.length"
               [pageIndex]="0"
               [pageSize]="5"
               [pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>

however It gives me an error. Error: cdk-table: Could not find column with id "Garage Name".. this one gives me hard time to figure out how to work on this. can someone point me where the error is. because I change the class for userData with the item of garageName instead of Id.

like image 765
Joshua Fabillar Avatar asked Nov 20 '17 14:11

Joshua Fabillar


3 Answers

Displayed columns array should match with the datasource.

displayedColumns = ['garageName', 'address', 'status', 'slots'];
like image 200
mohit uprim Avatar answered Nov 05 '22 22:11

mohit uprim


displayedColumns Names should Match with matColumnDef Names under ngContainer not as stated above You can have any name within your model/Array

like image 33
Maravarman Manoharan Avatar answered Nov 05 '22 23:11

Maravarman Manoharan


Same error occurs if the matColumnDef directive value doesn't match with columns object (typically named as displayedColumns) ex:

<ng-container matColumnDef="profileStatus">
  <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
  <td mat-cell *matCellDef="let row">{{ row?.profileStatus }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>

    displayedColumns: string[] = [
       'status'
  ];

Here the 'status' and 'profileStatus' don't match then also this error kicks in. To fix the names have to match

like image 2
sai amar Avatar answered Nov 06 '22 00:11

sai amar