Can't bind to 'dataSource' since it isn't a known property of 'table'
Asked Answered
K

22

155

I am new in angular 5 development. I am trying to develop a data table with angular material using the example provided here: "https://material.angular.io/components/table/examples".

I am getting an error saying Can't bind to 'dataSource' since it isn't a known property of 'table'.

enter image description here

Please help.

Koumis answered 8/5, 2018 at 7:26 Comment(11)
It's not table, just use <mat-table #table [dataSource]...>Intracellular
tried using the mat-table tag, then error disappears but I don't see my table in the view.Koumis
That's the right way to use the element, you must have other problems somewhere elseIntracellular
Can you provide me a working example using mat-table tag?Koumis
also, I exactly copied the code. No change in ts and html code.Koumis
what version of material are you using? The material table selector is different between v5 and v6.Sloat
"@angular/cdk": "^5.2.5", "@angular/common": "^5.2.0", "@angular/compiler": "^5.2.0", ` "@angular/core": "^5.2.0", "@angular/forms": "^5.2.0", "@angular/http": "^5.2.0", "@angular/material": "^5.2.5"`Koumis
The selector that you are using is from v6, and you have installed v5. You should take a look at the v5 examples v5.material.angular.io/components/table/examplesSloat
table is created but sorting is not workingKoumis
Got the solution. I forgot to add the MatSortModule in app.module.ts.Koumis
@RahulMunjal: If you don't mind, you could add your solution (if it works as expected) as answer, so that other users could benefit of it... this is the main target of STO.Lentamente
K
54

Thanx to @Jota.Toledo, I got the solution for my table creation. Please find the working code below:

component.html

<mat-table #table [dataSource]="dataSource" matSort>
  <ng-container matColumnDef="{{column.id}}" *ngFor="let column of columnNames">
    <mat-header-cell *matHeaderCellDef mat-sort-header> {{column.value}}</mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element[column.id]}}</mat-cell>
  </ng-container>

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

component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';
import { DataSource } from '@angular/cdk/table';

@Component({
  selector: 'app-m',
  templateUrl: './m.component.html',
  styleUrls: ['./m.component.css'],
})
export class MComponent implements OnInit {

  dataSource;
  displayedColumns = [];
  @ViewChild(MatSort) sort: MatSort;

  /**
   * Pre-defined columns list for user table
   */
  columnNames = [{
    id: 'position',
    value: 'No.',

  }, {
    id: 'name',
    value: 'Name',
  },
    {
      id: 'weight',
      value: 'Weight',
    },
    {
      id: 'symbol',
      value: 'Symbol',
    }];

  ngOnInit() {
    this.displayedColumns = this.columnNames.map(x => x.id);
    this.createTable();
  }

  createTable() {
    let tableArr: Element[] = [{ position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
      { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
      { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
      { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
      { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
      { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
    ];
    this.dataSource = new MatTableDataSource(tableArr);
    this.dataSource.sort = this.sort;
  }
}

export interface Element {
  position: number,
  name: string,
  weight: number,
  symbol: string
}

app.module.ts

imports: [
  MatSortModule,
  MatTableModule,
],
Koumis answered 8/5, 2018 at 9:16 Comment(1)
Using this I can make reusable table component which takes data array and columnNames array. This is far better solution than examples in material.angular.ioPeder
C
225

Remember to add MatTableModule in your app.module's imports i.e.

In Angular 9+

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

@NgModule({
  imports: [
    // ...
    MatTableModule
    // ...
  ]
})

Less than Angular 9

import { MatTableModule } from '@angular/material'  

@NgModule({
  imports: [
    // ...
    MatTableModule
    // ...
  ]
})
Connected answered 15/8, 2018 at 10:25 Comment(4)
This one works for me, most tutorials use the table tag and not the mat-table tag.Sech
This one works for me as well when you use the pagination also we have to do the same thing, I thinkBora
I had to make it import { MatTableModule } from '@angular/material/table'; to workPheon
100% @Connected if you get a can't bind with angular material it mostly due to a module not being imported. The above answer gets my 100% support.Karyoplasm
K
54

Thanx to @Jota.Toledo, I got the solution for my table creation. Please find the working code below:

component.html

<mat-table #table [dataSource]="dataSource" matSort>
  <ng-container matColumnDef="{{column.id}}" *ngFor="let column of columnNames">
    <mat-header-cell *matHeaderCellDef mat-sort-header> {{column.value}}</mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element[column.id]}}</mat-cell>
  </ng-container>

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

component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';
import { DataSource } from '@angular/cdk/table';

@Component({
  selector: 'app-m',
  templateUrl: './m.component.html',
  styleUrls: ['./m.component.css'],
})
export class MComponent implements OnInit {

  dataSource;
  displayedColumns = [];
  @ViewChild(MatSort) sort: MatSort;

  /**
   * Pre-defined columns list for user table
   */
  columnNames = [{
    id: 'position',
    value: 'No.',

  }, {
    id: 'name',
    value: 'Name',
  },
    {
      id: 'weight',
      value: 'Weight',
    },
    {
      id: 'symbol',
      value: 'Symbol',
    }];

  ngOnInit() {
    this.displayedColumns = this.columnNames.map(x => x.id);
    this.createTable();
  }

  createTable() {
    let tableArr: Element[] = [{ position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
      { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
      { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
      { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
      { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
      { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
    ];
    this.dataSource = new MatTableDataSource(tableArr);
    this.dataSource.sort = this.sort;
  }
}

export interface Element {
  position: number,
  name: string,
  weight: number,
  symbol: string
}

app.module.ts

imports: [
  MatSortModule,
  MatTableModule,
],
Koumis answered 8/5, 2018 at 9:16 Comment(1)
Using this I can make reusable table component which takes data array and columnNames array. This is far better solution than examples in material.angular.ioPeder
V
18
  • Angular Core v6.0.2,
  • Angular Material, v6.0.2,
  • Angular CLI v6.0.0 (globally v6.1.2)

I had this issue when running ng test, so to fix it, I added to my xyz.component.spec.ts file:

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

And added it to imports section in TestBed.configureTestingModule({}):

beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ ReactiveFormsModule, HttpClientModule, RouterTestingModule, MatTableModule ],
      declarations: [ BookComponent ],
      schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
    })
    .compileComponents();
}));
Vanhomrigh answered 5/8, 2018 at 10:25 Comment(2)
Testing spec the answer here as well. Solved for Angular 7.Swenson
Thank you! So many questions on SO similar to this but yours is the only answer I found like this, problem was in .spec.ts for me as well.Abnormal
I
14

if your "import { MatTableModule } from '@angular/material';" is on a shared module, make sure you export it.

sharedmodule.ts:

import { MatTableModule } from '@angular/material' 

@NgModule({
  imports: [
    // ...
    MatTableModule
    // ...
  ],
  exports:[ MatTableModule ]
})

then on your custom module where you define the component that use material table:

custommodule.ts:

@NgModule({
imports: [ sharedmodule ]     
})
Irrespirable answered 30/3, 2019 at 1:51 Comment(0)
B
10

Material example is using the wrong table tags. Change

<table mat-table></table>
<th mat-header-cell></th>
<td mat-cell></td>

<tr mat-header-row></tr>
<tr mat-row></tr>

to

<mat-table></mat-table>
<mat-header-cell></mat-header-cell>
<mat-cell></mat-cell>

<mat-header-row></<mat-header-row>
<mat-row></<mat-row>
Bunyan answered 14/11, 2018 at 19:31 Comment(0)
K
9

For Angular 7

Check where is your table component located. In my case it was located like app/shared/tablecomponent where shared folder contains all sub components But I was importing material module in Ngmodules of app.module.ts which was incorrect. In this case Material module should be imported in Ngmodules of shared.module.ts And it works.

There is NO NEED to change 'table' to 'mat-table' in angular 7.

Angular7 - Can't bind to 'dataSource' since it isn't a known property of 'mat-table'

Kazue answered 16/1, 2019 at 11:45 Comment(0)
H
6

In my case the trouble was I didn't put the components that contain the datasource in the declarations of main module.

NgModule({
  imports: [
    EnterpriseConfigurationsRoutingModule,
    SharedModule
  ],
  declarations: [
    LegalCompanyTypeAssignComponent,
    LegalCompanyTypeAssignItemComponent,
    ProductsOfferedListComponent,
    ProductsOfferedItemComponent,
    CustomerCashWithdrawalRangeListComponent,
    CustomerCashWithdrawalRangeItemComponent,
    CustomerInitialAmountRangeListComponent,
    CustomerInitialAmountRangeItemComponent,
    CustomerAgeRangeListComponent,
    CustomerAgeRangeItemComponent,
    CustomerAccountCreditRangeListComponent, //<--This component contains the dataSource
    CustomerAccountCreditRangeItemComponent,
  

  ],

The component contains the dataSource:

export class CustomerAccountCreditRangeListComponent implements OnInit {

  @ViewChild(MatPaginator) set paginator(paginator: MatPaginator){
    this.dataSource.paginator = paginator;
  }
  @ViewChild(MatSort) set sort(sort: MatSort){
    this.dataSource.sort = sort;
  }

  dataSource = new MatTableDataSource(); //<--The dataSource used in HTML
  loading: any;
  resultsLength: any;
  displayedColumns: string[] = ["id", "desde", "hasta", "tipoClienteNombre", "eliminar"];
  data: any;

  constructor(
    private crud: CustomerAccountCreditRangeService,
    public snackBar: MatSnackBar,
    public dialog: MatDialog,
    private ui: UIComponentsService
  ) {
  }

This is for Angular 9

Hetero answered 13/12, 2020 at 22:12 Comment(0)
A
4

I was also breaking my head for a long time with this error message and later I identified that I was using [datasource] instead of [dataSource].

Angularity answered 17/3, 2019 at 12:26 Comment(1)
Thanks for this! I had the same issue with a pug converter online from: html-to-pug.com, it copied the [dataSource] input and converted it to [datasource]Plasmasol
W
4

I imported MatTableModule in app-routing module and the error was gone.

Wiskind answered 11/9, 2021 at 11:49 Comment(0)
B
2

I had the same issue! Although I rectified it my adding the import of MatTableModule into the mycustom module.ts , instead of adding it in app.module.ts

Note: As I have created a custom module(inbox.module.ts) and created components in it, hence the declarations of those modules were created in inbox.module.ts, due to which the import of MatTableModule was suppose to be done in inbox.module.ts and not in app.module.ts

Brushwork answered 21/1, 2022 at 10:2 Comment(0)
D
2

In my case, I was adding MatTableModule in the app module, but I have nested components like so:

app module
|__________dashboard module
           |_________________user module
                             |___________plans module

I added MatTableModule in the direct parent of plans module which is user module, then it worked.

Dictaphone answered 29/5, 2022 at 10:34 Comment(0)
I
2

Step 1 : open -> app.module.ts

Step 2 : import below

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

Step 3: And under import add MatTableModule as below

@NgModule({
  imports: [
     
   MatTableModule
    
  ]
})

Below is the screenshot to refer:

enter image description here

Inaction answered 15/7, 2023 at 8:8 Comment(0)
K
1

For those who just use the Angular CDK and not Angular Material, instead of importing MatTableModule import CdkTableModule:

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

@NgModule({
imports: [
    ...
    CdkTableModule,
    ...
],
Kedge answered 25/3, 2022 at 16:43 Comment(0)
P
1

Once on my angular 13, I have got this same issue because I forgot to add my component in the app module in which I have imported MatTableModule.

Patroon answered 27/6, 2022 at 11:0 Comment(0)
W
1

For me the problem was very strange, but I could reproduce it, which means it could happen to other people.

My Angular version was 14. When I wanted to add Material to my project with ng add @angular/material the material version it wanted to install, and asked me was 7.0.0 (which I missed and installed anyway).

When I had taken a look at other projects, their material version was much higher: 14.2.6.

In the end what solved the issue for me was giving a specific angular material version for the ng add command. You'll have to check what your current version is and add that to the command. For example:

ng add @angular/[email protected]
Wanigan answered 6/12, 2022 at 11:7 Comment(0)
L
1

In the case of Storybook, you need to ensure MatTableModule is imported in your stories moduleMetadata:

    moduleMetadata({
      declarations: [ModGridComponent],
      imports: [
        CommonModule,
        MatTableModule
      ]
    })

Labellum answered 6/9, 2023 at 10:42 Comment(0)
A
0

Remember to import the MatTableModule module and remove the table element show below for reference.
wrong implementation
<table mat-table [dataSource]=”myDataArray”> ... </table>
correct implementation:
<mat-table [dataSource]="myDataArray"> </mat-table>

Aldose answered 27/11, 2018 at 6:20 Comment(0)
S
0

The problem is your angular material version, I have the same, and I have resolved this when I have installed the good version of angular material in local.

Hope it solve yours too.

Smallsword answered 29/11, 2018 at 15:57 Comment(0)
I
0

I have resolved it by change [data-source]="dataSource" to [dataSource]="dataSource" in my name.component.html

Impi answered 9/7, 2022 at 4:16 Comment(0)
N
0

I have separate modules for each feature and adding the feature module that contained the MatTableModule in the app.module has fixed it.

Nosh answered 6/4, 2023 at 12:38 Comment(0)
W
-1

If you've tried everything mentioned here and it didn't work, make sure you also have added angular material to your project. If not, just run the following command in the terminal to add it:

ng add @angular/material

After it successfully gets added, wait for the project to get refreshed, and the error will be automatically gone.

Wide answered 30/12, 2020 at 14:6 Comment(0)
L
-4

Please see your dataSource varibale doesn't get the data from the server or dataSource is not assigned to the expected format of data.

Louvain answered 8/5, 2018 at 7:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.