0
votes

this TypeError: Cannot set property 'active' of undefined keeps occurring in the console and the sorting does not work at all. please help me to figure out what should I do to sort the table according to the selected value of mat-select.

.component.ts file

import {Component, OnInit, ViewChild} from '@angular/core';
import { FormControl } from '@angular/forms';
import {MatTableDataSource} from '@angular/material/table';
import {PointTableService} from "./point-table.service";
import {MatSort, Sort} from "@angular/material/sort";

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

  displayedColumns: string[] = ['club', 'points', 'wins', 'looses', 'draws', 'goals_scored', 'goals_received'];
  dataSource: MatTableDataSource<PointTable>
  disableSelect = new FormControl(false);

  constructor(private tableService: PointTableService ) { }

  @ViewChild(MatSort) sort: MatSort;

  selectedColumn = 'points';

  ngOnInit(): void {
    this.dataSource = new MatTableDataSource<PointTable>();

    this.tableService.getClubs().subscribe((data) => {
      this.dataSource = new MatTableDataSource<PointTable>(data['response']);
    })

    this.dataSource.sort = this.sort;
    this.changeSortedColumn();
  }

  changeSortedColumn() {
    const sortState: Sort = {active: this.selectedColumn, direction: 'asc'};
    this.sort.active = sortState.active;
    this.sort.direction = sortState.direction;
    this.sort.sortChange.emit(sortState);
  }

}

export interface PointTable {
  clubName: string;
  points: number;
  wins: number;
  defeats: number;
  draws: number;
  goalsScored: number;
  goalsReceived: number;
}

.component.html

<h1>Points Table</h1>
<mat-form-field appearance="fill" class="sort-select">
    <mat-label>Sort by</mat-label>
    <mat-select [(value)]="selectedColumn" (selectionChange)="changeSortedColumn()">
      <mat-option value="points" id="points">Points</mat-option>
      <mat-option value="wins" id="wins">Wins</mat-option>
      <mat-option value="goalsScored" id="goalsScored">Goals Scored</mat-option>
    </mat-select>
</mat-form-field>

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

    <ng-container matColumnDef="club">
        <th mat-header-cell *matHeaderCellDef> CLUB </th>
        <td mat-cell *matCellDef="let element"> {{element.clubName}} </td>
    </ng-container>


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


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


    <ng-container matColumnDef="looses">
        <th mat-header-cell *matHeaderCellDef> L </th>
        <td mat-cell *matCellDef="let element"> {{element.defeats}} </td>
    </ng-container>


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


    <ng-container matColumnDef="goals_scored">
        <th mat-header-cell *matHeaderCellDef> GS </th>
        <td mat-cell *matCellDef="let element"> {{element.goalsScored}} </td>
    </ng-container>

    <ng-container matColumnDef="goals_received">
        <th mat-header-cell *matHeaderCellDef> GR </th>
        <td mat-cell *matCellDef="let element"> {{element.goalsReceived}} </td>
    </ng-container>

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

reference code for my program https://stackblitz.com/edit/angular-mat-sort-default-hwa9q2?file=app%2Ftable-sorting-example.ts

1
Move changeSortedColumn method inside subscribe blockChellappan வ

1 Answers

0
votes

async functions work without waiting. So if you want to assign something with async request you should do it inside subscribe.

ngOnInit(): void {
    this.dataSource = new MatTableDataSource<PointTable>();

    this.tableService.getClubs().subscribe((data) => {
      this.dataSource = new MatTableDataSource<PointTable>(data['response']);
       this.dataSource.sort = this.sort;
       this.changeSortedColumn();
    })
  }