Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material - mat-table not rendering data from rest api

I've been trying to implement this table example from Angular Material without luck

I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

My suspicions are that maybe the data isn't quite loaded yet, when the table is rendered. Any help is appreciated, thanks!

lap.component.ts

import {Component, OnInit, ViewChild} from '@angular/core';
import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material';
import {Router} from '@angular/router';
import {LapService} from '../shared/services/lap.service';
import {Lap} from '../shared/model/lap.model';

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

  displayedColumns = ['id', 'year', 'lap', 'shortcut flag', 'start place', 'destination place', 'length', 'height difference'];
  dataSource: MatTableDataSource<Lap>;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;


  constructor(public rest: LapService, private router: Router) {
  }

  ngOnInit() {
    this.dataSource = new MatTableDataSource(this.getLaps());
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }


  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  getLaps() {
    this.rest.getLaps().subscribe((data: {}) => {
      console.log(data);
      console.log('Laps');
      return data;
    });
  }
}

lap.component.html

<mat-form-field>
  <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>

<div class="mat-elevation-z8">
  <table mat-table [dataSource]="dataSource" matSort>

    <!-- ID Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
      <td mat-cell *matCellDef="let row "> {{row.id}} </td>
    </ng-container>

    <!-- Year Column -->
    <ng-container matColumnDef="year">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Year </th>
      <td mat-cell *matCellDef="let row"> {{row.year}} </td>
    </ng-container>

    <!-- Lap Column -->
    <ng-container matColumnDef="lap">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Lap </th>
      <td mat-cell *matCellDef="let row"> {{row.lap}} </td>
    </ng-container>

    <!-- Shortcut Column -->
    <ng-container matColumnDef="shortcut flag">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Shortcut Flag </th>
      <td mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.shortcut_flag}} </td>
    </ng-container>

    <!-- Start Column -->
    <ng-container matColumnDef="start place">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Start Place </th>
      <td mat-cell *matCellDef="let row"> {{row.start_place}} </td>
    </ng-container>

    <!-- Destination Column -->
    <ng-container matColumnDef="destination place">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Destination Place </th>
      <td mat-cell *matCellDef="let row"> {{row.destination_place}} </td>
    </ng-container>

    <!-- Length Column -->
    <ng-container matColumnDef="length">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Length </th>
      <td mat-cell *matCellDef="let row"> {{row.length}} </td>
    </ng-container>

    <!-- Height Column -->
    <ng-container matColumnDef="height difference">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Height Difference </th>
      <td mat-cell *matCellDef="let row"> {{row.height_difference}} </td>
    </ng-container>

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

  <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>

lap.service.ts

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class LapService {

  private lapUrl = 'http://localhost:8080/api/lap';
  private httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  };

  constructor(private http: HttpClient) { }

  getLaps(): Observable<any> {
    return this.http.get(this.lapUrl, this.httpOptions).pipe(
      map(this.extractData));
  }

  private extractData(res: Response) {
    return res || {}; // If 'res' is null, it returns empty object
  }

}
like image 713
BlueScoreMan Avatar asked Feb 07 '19 14:02

BlueScoreMan


1 Answers

You need to create new MatTableDataSource() and then on data receiving pass that data to dataSource.data array.

 ngOnInit() {
   // this.dataSource = new MatTableDataSource(this.getLaps());
    this.dataSource = new MatTableDataSource(); // create new object
    this.getLaps(); // forgeted this line
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
 }

   getLaps() {
     this.rest.getLaps().subscribe((data: {}) => {
       console.log(data);
       console.log('Laps');
       this.dataSource.data = data; // on data receive populate dataSource.data array
       return data;
    });
  }
like image 139
Nenad Radak Avatar answered Sep 29 '22 03:09

Nenad Radak