0

I'm trying to dynamically populate a table using the following code:

teams.component.ts

import { Component, OnInit } from '@angular/core';
import { first } from 'rxjs/operators';
import { TeamService } from 'src/app/services/team.service';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

@Component({
  selector: 'app-teams',
  templateUrl: './teams.component.html',
  styleUrls: ['./teams.component.scss']
})
export class TeamsComponent implements OnInit {
  public teams : any; 

  tableCols = ['id', 'name'];

  constructor(private teamService : TeamService) { }

  ngOnInit(): void {
    this.teamService.getTeams().pipe(first()).subscribe(
      data => {
        this.teams = data.results
      },
      error => {
        console.log(error.error)
      }
    ) 
  }

}

teams.component.html

<app-table [tableData]="teams" [tableColumns]="tableCols"></app-table>

table.component.ts

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { MatSort } from '@angular/material/sort';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.scss']
})
export class TableComponent implements OnInit {
  tableDataSrc: any;
  // tslint:disable-next-line: no-input-rename
  @Input('tableColumns') tableCols: string[];
  @Input() tableData: {}[] = [];

  @ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;


  constructor() { }

  ngOnInit() {
    this.tableDataSrc = new MatTableDataSource(this.tableData);
    this.tableDataSrc.sort = this.sort;
    this.tableDataSrc.paginator = this.paginator;
  }

}

table.component.html

<div class="mat-elevation-z8">
<table mat-table [dataSource]="tableDataSrc" matSort class="mat-elevation-z8">
    <ng-container *ngFor="let col of tableCols">
    <ng-container matColumnDef="{{ col }}">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>
        {{ col | titlecase }}
        </th>
        <td mat-cell *matCellDef="let profile">{{ profile }}</td>
    </ng-container>
    </ng-container>

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

<mat-paginator [pageSizeOptions]="[1, 2, 3, 5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>

A 'team' object looks like the following:

{'id': 9, 'name': 'FC Barcelona'} and the teams variable is a list of these objects.

When I navigate to the teams page the table is rendered and stays empty, what am I doing wrong here?

1
  • Could be that ngOnInit in table.component is called before the getTeams() TeamsComponent in finishes? Try to have another method that has input of the info and not ngOnInit. Add console.log to see the life cycle hooks Commented May 17, 2020 at 21:03

1 Answer 1

1

try replacing this part in table.component.ts

  ngOnInit() {
    this.tableDataSrc = new MatTableDataSource(this.tableData);
    this.tableDataSrc.sort = this.sort;
    this.tableDataSrc.paginator = this.paginator;
  }

with this

  ngOnChanges(changes: SimpleChanges) {
      if(changes.tableData.currentValue) {
          this.tableDataSrc = new MatTableDataSource(this.tableData);
          this.tableDataSrc.sort = this.sort;
          this.tableDataSrc.paginator = this.paginator;
      }
  }

The problem is teams field in TeamsComponent gets initialized after (due to async operation) TableComponents OnInit phase. If you change ngOnInit with ngOnChanges whenever teams field changes TableComponent becomes aware of it.

Further reading: https://angular.io/guide/lifecycle-hooks#using-change-detection-hooks

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.