Reputation: 55
I'm struggling with the Angular mat-table library. I got an app with a Node.js backend and an Angular frontend. The node app provides data from a MySQL database in JSON.
Now I want to display this data in a mat-table. I have logged the data in the console, which allows me to see that the data is actually retrieved but just not displayed.
However, the HTML table is empty:
This is my Angular component:
component.html
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 demo-table">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>ID</th>
<td mat-cell *matCellDef="let element">{{element.id}}</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{element.name}}</td>
</ng-container>
<ng-container matColumnDef="pop">
<th mat-header-cell *matHeaderCellDef>Population</th>
<td mat-cell *matCellDef="let element">{{element.population}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr
mat-row
(click)="clickedRows.add(row)"
[class.demo-row-is-clicked]="clickedRows.has(row)"
*matRowDef="let row; columns: displayedColumns;"
></tr>
</table>
component.ts
import {Component, OnInit,ViewChild} from '@angular/core';
import { Player } from '../player';
import { PlayerService } from '../player.service';
import { MatTableDataSource } from '@angular/material/table';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort, SortDirection} from '@angular/material/sort';
/**
* @title Binding event handlers and properties to the table rows.
*/
@Component({
selector: 'app-players',
styleUrls: ['players.component.css'],
templateUrl: 'players.component.html',
})
export class PlayersComponent implements OnInit {
displayedColumns: string[] = ['id', 'name', 'pop'];
dataSource = new MatTableDataSource<Player>();
@ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
@ViewChild(MatSort, { static: true }) sort!: MatSort;
constructor(private playerService:PlayerService) { }
ngOnInit(): void {
this.getPlayers();
}
getPlayers() {
this.playerService.getPlayers().subscribe(players => {
console.log(players);
this.dataSource.data = players;
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
clickedRows = new Set<Player>();
}
player.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { Player } from './player';
@Injectable({
providedIn: 'root'
})
export class PlayerService {
constructor(private http: HttpClient) { }
rootURL = '/api';
getPlayers(): Observable<Player[]> {
return this.http.get<Player[]>(this.rootURL+ '/players');
}
}
Any ideas on this?
EDIT: Could it have something to do with how the array comes back from the API? In Node.js it is retrieved with sequelize and maybe it is the response?
// Get all Players
exports.findAll = (req, res) => {
Player.findAll().then((players) => {
// Send all players as response
res.status(200).json({
status: true,
data: players,
});
});
};
Upvotes: 1
Views: 2131
Reputation: 51125
The data returned based on the screenshot and Node.js API is not Player
array, but it is an object with status
and data
properties.
{
"status": 200,
"data": [...]
}
This line expected that HTTP GET to receive Player
array which is conflict with your data.
this.http.get<Player[]>(this.rootURL+ '/players');
Hence, it returns Observable with an empty array and your <mat-table>
will not show the data.
Transform the data to Player
array with map
rxjs operator.
import { map } from 'rxjs';
getPlayers(): Observable<Player[]> {
return this.http
.get(this.rootURL+ '/players')
.pipe(map((response: any) => response.data as Player[]));
}
Upvotes: 2
Reputation: 2246
Create a instance of MatTableDataSource and assign to data Source. Try this option
this.dataSource = new MatTableDataSource(players);
this.dataSource.sort = this.sort;
Ref: Using HTTP GET request to fetch data in an Angular Material Table
Upvotes: 0