Reputation: 366
I am trying to use the Angular Material Table with selection, it says on the browser console 'data' is undefined here . The error on the console says "Cannot read property 'data' of undefined in Material Table with selection" however the table is displayed with the data from Json file.
Here is the full code for the .ts file
export class GetUserComponent implements OnInit
isFetching = false;
displayedColumns: string[] = ['select','title','content'];
dataSource : MatTableDataSource<User>;
selection = new SelectionModel<User>(true, []);
constructor(private http: HttpClient, private userService : UserService) { }
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
**const numRows = this.dataSource.data.length;**
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row));
}
/** The label for the checkbox on the passed row */
checkboxLabel(row?: User): string {
if (!row) {
return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.id + 1}`;
}
This is the HTML table
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"
[aria-label]="checkboxLabel()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
[aria-label]="checkboxLabel(row)">
</mat-checkbox>
</td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<ng-container matColumnDef="content">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Content </th>
<td mat-cell *matCellDef="let element"> {{element.content}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
(click)="selection.toggle(row)">
</tr>
</table>
Please advise on this.
Upvotes: 0
Views: 5449
Reputation: 326
This thing worked for me. import table from angular/material and create an
instance of it using viewchild. get your user data and set displayedColumns in
ngOnInit()
,In ngAfterContentChecked()
you need to create MatTableDataSource
instance and set this instance to table.dataSource
in ngAfterViewInit()
check
below
import { MatTable, MatTableDataSource } from '@angular/material/table';
export class GetUserComponent implements OnInit {
@ViewChild(MatTable, {static:false}) table: MatTable<any>;
dataSource :any;
costructor(private appService:AppService){}
ngOnInit() {
this.appService.getUsers().subscribe(data => {
this.userData= data;
});
this.displayedColumns = ['select','title','content'];
}
ngAfterViewInit() {
this.table.dataSource = this.dataSource;
}
ngAfterContentChecked(){
this.dataSource = new MatTableDataSource (this.userData);
}
}
you can check my stackblitz here
https://stackblitz.com/edit/angular-dynamicexamples
Upvotes: 2