LETSDRUM
LETSDRUM

Reputation: 133

mat-table dataSource doesn't work when using REST API

I am unable to put data in a Material Table.

I made a Block model with fields like id, date, etc. data.service is where the API call is and the function getAllBlock() returns the blocks. I tried it in app.component.html and it works.

document-list.component.ts

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { DataService } from '../data.service';
import { Block } from '../models/block.model';

@Component({
    selector: 'app-document-list',
    templateUrl: './document-list.component.html',
    styleUrls: ['./document-list.component.sass']
})
export class DocumentListComponent implements OnInit {
    blocks: Block[];
    //DataSource and columns for DataTable
    displayedColumns: string[] = ['Id', 'Date', 'Data', 'Hash', 'PreviousHash'];
    dataSource = new MatTableDataSource<Block>(this.blocks);

    //Filter (search)
    applyFilter(filterValue: string) {
        this.dataSource.filter = filterValue.trim().toLowerCase();
    }

    constructor(private dataService: DataService) { }

    ngOnInit(){
        return this.dataService.getAllBlock()
        .subscribe(data => this.blocks = data);
    }
}

document-list.component.html

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

    <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
        <!-- ID Column -->
        <ng-container matColumnDef="Id">
            <th mat-header-cell *matHeaderCellDef>ID</th>
            <td mat-cell *matCellDef="let element"> {{element.Id}} </td>
        </ng-container>

        <!-- Date Column -->
        <ng-container matColumnDef="Date">
            <th mat-header-cell *matHeaderCellDef>Timestamp</th>
            <td mat-cell *matCellDef="let element"> {{element.Date}} </td>
        </ng-container>

        <!-- Data Column -->
        <ng-container matColumnDef="Data">
            <th mat-header-cell *matHeaderCellDef>Data</th>
            <td mat-cell *matCellDef="let element"> {{element.Data}} </td>
        </ng-container>

        <!-- Hash Column -->
        <ng-container matColumnDef="Hash">
            <th mat-header-cell *matHeaderCellDef>Hash</th>
            <td mat-cell *matCellDef="let element"> {{element.Hash}} </td>
        </ng-container>

        <!-- Previous Hash -->
        <ng-container matColumnDef="PreviousHash">
            <th mat-header-cell *matHeaderCellDef>PrevHash</th>
            <td mat-cell *matCellDef="let element"> {{element.PreviousHash}} </td>
        </ng-container>
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
</div>

I don't know how to insert data into the table. What's wrong in what I've done or where is the problem?

Upvotes: 3

Views: 2624

Answers (1)

nash11
nash11

Reputation: 8650

You're dealing with async data so initially this.blocks is undefined. You need to create the dataSource once this.blocks is defined which is after you subscribe to getAllBlock(). It also doesn't make sense to use return here since you just get the data from the subscribe method. So just simply call getAllBlock() instead.

Here's how your code should look now.

dataSource: MatTableDataSource<Block>;

ngOnInit() {
    this.dataService.getAllBlock().subscribe(data => {
        this.blocks = data
        this.dataSource = new MatTableDataSource<Block>(this.blocks);
    });
}

Upvotes: 9

Related Questions