I'm trying to add a table in my Angular app from Angular Material@17.2.1 (as shown here ).
I copied/pasted the code from the official Angular Material documentation but I still get the error:
Cannot bind to 'dataSource' as it is not a known property of 'table'
I tried the following:
Replace the table tag with mat-table, resulting in
mat-table is not a known element
Removing the square brackets in [dataSource]="dataSource" as dataSource="dataSource" , resulting in (this time an error in the web developer console, this might be the solution, but I don't know how to fix it even after some searches)
Cannot be bound to 'matHeaderRowDef' as it is not a known property of 'tr' (used in the '_UsersComponent' component template).
importing MatTableModule from '@angular/material' instead of '@angular/material/table' in app.module.ts , resulting in
@angular/material does not have any exported MatTableModule members
Add it import {CdkTableModule} from '@angular/cdk/table'; and import it, without changing anything.
The MatTableModule is declared and imported in app.module.ts , where UsersComponent is also declared and imported for use.
Here are all the versions used in the project:
@angular-devkit/architect 0.1702.2
@angular-devkit/build-angular 17.2.2
@angular-devkit/core 17.2.2
@angular-devkit/schemas 17.2.2
@angular/cdk 17.2.1
@angular/cli 17.2.2
@angular/material 17.2.1
@schemes/angular 17.2.2
rxjs 7.8.1
typescript 5.3.3
zone.js 0.14.4
Here is the content of my app.module.ts file:
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { BrowserModule } from '@angular/platform-browser';
import { MatListModule } from '@angular/material/list';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatSidenavModule } from '@angular/material/sidenav';
import { AppComponent } from './app.component';
import { TopbarComponent } from './topbar/topbar.component';
import { LeftmenuComponent } from './leftmenu/leftmenu.component';
import { NavleftbarComponent } from './navleftbar/navleftbar.component';
import { MatIconModule } from '@angular/material/icon';
import {MatTableModule} from '@angular/material/table';
import { MatButtonModule } from '@angular/material/button';
import {CdkTableModule} from '@angular/cdk/table';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { UsersComponent } from './users/users.component';
@NgModule({
declarations: [
AppComponent,
TopbarComponent,
LeftmenuComponent,
NavleftbarComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MatToolbarModule,
MatSidenavModule,
MatListModule,
MatButtonModule,
MatIconModule,
MatTableModule,
UsersComponent,
CdkTableModule
],
providers: [
provideAnimationsAsync()
],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is the users.component.ts file contents:
import { Component } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
export interface UserElement {
firstname: string;
lastName: string;
email: string;
microsoftEmail: string;
class: string;
}
const ELEMENT_DATA: UserElement[] = [{
firstname: "Pierrick",
lastName: "MARTELLIERE",
email: "p.martelliere@gmail.com",
microsoftEmail: "pierrick@coxidev.com",
class: "GPME24"
}];
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrl: './users.component.css',
standalone: true,
})
export class UsersComponent {
displayedColumns: string[] = ['firstName', 'lastName', 'email', 'microsoftEmail', 'class'];
dataSource = ELEMENT_DATA;
clickedRows = new Set<UserElement>();
}
And users.component.html:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 demo-table">
<ng-container matColumnDef="firstName">
<th mat-header-cell *matHeaderCellDef> Prénom </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<ng-container matColumnDef="lastName">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef> Email </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<ng-container matColumnDef="microsoftEmail">
<th mat-header-cell *matHeaderCellDef> Compte Microsoft </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<ng-container matColumnDef="class">
<th mat-header-cell *matHeaderCellDef> Classe </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<!-- Copyright 2024 Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://angular.io/license -->
I don't really see what I'm missing, some help would be welcome.
The problem appears to be related to the fact that UsersComponent is a standalone component ( standalone: true ). In Angular 17, standalone components do not automatically inherit modules imported in AppModule ; they must explicitly import the modules they use.
That's why Angular doesn't recognize directives like mat-table , matHeaderRowDef or matRowDef , even if MatTableModule is in AppModule .
Try adding the imports directly to the component:
@Component({
selector: 'app-users',
standalone: true,
imports: [MatTableModule],
templateUrl: './users.component.html',
styleUrl: './users.component.css'
})
Alternatively, if you don't want to use standalone components, remove standalone: true and declare UsersComponent inside AppModule declarations .
Additionally, check that UsersComponent is declared or imported consistently; currently it appears to be set as standalone but is also being used from a traditional module, which is often the cause of these types of errors.