'How to sort data in Angular mat-table

I can't find a solution and the console doesn't give me any errors. I have followed step by step few tutorials but there was no solution. This is how my request.component.ts looks like

import { Component, OnInit, ViewChild } from '@angular/core';
import { DenyReasonRequestFormComponent } from '../deny-reason-request-form/deny-reason-request-form.component'
import { MatDialog } from '@angular/material/dialog';
import { ViewComponent } from '../view/view.component';
import { MatDialogConfig } from '@angular/material/dialog';
import { EmpFilter } from  'src/app/models/empfilter';
import { MatTableDataSource } from '@angular/material/table';
import { MatSelectChange } from '@angular/material/select';
import { HolidayRequestsService } from 'src/app/services/holiday-requests/holiday-requests.service';
import { __core_private_testing_placeholder__ } from '@angular/core/testing';
import { HolidayRequests } from 'src/app/models/holiday-requests.model';
import { HttpClient } from '@angular/common/http';
import { MatSort } from '@angular/material/sort';
import { AnyFn } from '@ngrx/store/src/selector';
import { reduceEachTrailingCommentRange } from 'typescript';

export interface EmployeeData {
  id: number;
  name: string;
}

@Component({
  selector: 'app-requests',
  templateUrl: './requests.component.html',
  styleUrls: ['./requests.component.css'],
  providers: [ HolidayRequestsService ]
})
export class RequestsComponent implements OnInit {
  id: number;
  name: string;
  _holidayRequests = new MatTableDataSource<HolidayRequests>();
  startDate:Date;
  empFilters: EmpFilter[]=[];
  defaultValue = "All";
  filterDictionary= new Map<string,string>();

  public style = "grey"
   public displayedColumns = [
     'name',
     'date',
     'status',
     'view',
  ];

  @ViewChild(MatSort) sort: MatSort;

  public DurationOfHolidaysLeave: string[] = ['All', '2021', '2022', '2023']

  constructor(public dialog: MatDialog,
              public http: HttpClient,
              private _holidayRequestsService : HolidayRequestsService,
              ) {}

    view(id:number) {
      const dialogOptions = new MatDialogConfig();
      dialogOptions.disableClose = false;
      dialogOptions.data = {ID:id, parent: this };
      dialogOptions.maxWidth = '45vw';
      dialogOptions.maxHeight = '74vh';
      dialogOptions.height = '100%';
      dialogOptions.width = '100%';
      this.dialog.open(ViewComponent, dialogOptions);
    }


public onApprove(request): void {
    request.Status = 'Approved';
    this.http.put<any>(`http://localhost:1339/holiday-requests/${request.id}`, request)
    .subscribe((res) => {})
  }

public openDialog(request): void {
    const dialogRef = this.dialog.open(DenyReasonRequestFormComponent, {
      data: { request }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        request.Status = 'Denied';
        this.http.put<any>(`http://localhost:1339/holiday-requests/${request.id}`, request)
        .subscribe((res) => {})
      }
      console.log('The dialog was closed');
    })
  };

  ngOnInit(): void {
    this.empFilters.push({
      name: 'Year', options: this.DurationOfHolidaysLeave,
      defaultValue: this.defaultValue
    });

    console.log(this._holidayRequests);

    this._holidayRequestsService.getHolidayRequests().subscribe(
      (results) =>
      {
        this._holidayRequests = new MatTableDataSource(results);
        this._holidayRequests.sort = this.sort;
      }
    )

    this._holidayRequestsService.getHolidayRequests().subscribe(
      (results)=>
      {
        this._holidayRequests = new MatTableDataSource(results)
      //  console.log(this._holidayRequests)
        this._holidayRequests.filterPredicate = function (record, filter) {
          var map = new Map(JSON.parse(filter));
          let isMatch = false;
          for (let [key, value] of map) {
            isMatch = (value == "All")
              || (new Date(record['starting_date']).getFullYear() == value
              || (new Date(record['ending_date']).getFullYear() == value));
            if (!isMatch) return false;
          }
          return isMatch;
        }
      }
    );
    }

  applyEmpFilter(ob:MatSelectChange,empfilter:EmpFilter) {
    console.log('applyEmpFilter', this._holidayRequests)
    this.filterDictionary.set(empfilter.name,ob.value);
    var jsonString = JSON.stringify(Array.from(this.filterDictionary.entries()));
    this._holidayRequests.filter = jsonString;
  }
}

There is filtering already finished since this is a group project. This is how my HTML file looks like:

<app-breadcumb-toolbar breadcumbPath="New Requests"></app-breadcumb-toolbar>
<div class="container">
    <div class="column column-12">
        <div class="actionToolbar">
            <mat-form-field style="max-width: 150px;" appearance="fill">
                <select matNativeControl required>
                    <option value="Team1">Team</option>
                    <option value="Team2">Team2</option>
                    <option value="Team3">Team3</option>
                    <option value="Team4">Team4</option>
                </select>
            </mat-form-field>

            <!-- <mat-form-field style="margin-left: 30px; max-width: 150px;" appearance="fill">
                <select matNativeControl required>
                    <option value="2022">2022</option>
                    <option value="2021">2021</option>
                    <option value="2020">2020</option>
                </select>
            </mat-form-field> -->

            <mat-form-field  style="margin-left: 30px; max-width: 150px;" appearance="fill" *ngFor="let empfilter of empFilters">
                <mat-label>{{ empfilter.name }}</mat-label>
                <mat-select
                  [(value)]="empfilter.defaultValue"
                  (selectionChange)="applyEmpFilter($event, empfilter)"
                >
                  <mat-option *ngFor="let op of empfilter.options" [value]="op">
                    {{ op }}
                  </mat-option>
                </mat-select>
              </mat-form-field>

            <button class="holiday-approved-button">Approved</button>
            <button class="holiday-denied-button">Denied</button>
        </div>
    </div>
    <div class="column column-12">
        <table mat-table [dataSource]="_holidayRequests" matSort class="mat-elevation-z8" style="text-align: center;">
            <ng-container matColumnDef="name">
                <th style="width: 5%; text-align: center;" mat-header-cell *matHeaderCellDef mat-sort-header=""> Name</th>
                <td mat-cell *matCellDef="let request"> {{ request.id }} <!-- {{request.employee.firstName}} {{request.employee.lastName}}  --> </td>
            </ng-container>

            <ng-container matColumnDef="date">
                <th style="width: 5%; text-align: center;" mat-header-cell *matHeaderCellDef> Duration of holiday leave
                </th>
                <td mat-cell *matCellDef="let request"> {{ request.starting_date }} - {{ request.ending_date }}  </td>
            </ng-container>

            <ng-container matColumnDef="status">
                <th style="width: 5%; text-align: center;" mat-header-cell *matHeaderCellDef>Status</th>
                <td mat-cell *matCellDef="let request"
                    [ngStyle]="{'background-color': request.Status=='Denied' ? '#caceca' : (request.Status=='Approved' ? '#c3ffc3' : 'white')}">
                    <div>
                        {{request.Status === "Pending" ? null : request.Status}}
                        <div class="approve-deny-option"
                            [ngStyle]="{'display': request.Status=='Pending' ? 'flex' : 'none'}">
                            <button class="approve-button" (click)="onApprove(request)">A</button>
                            <button class="deny-button" (click)="openDialog(request)">D</button>
                        </div>
                    </div>
                </td>
            </ng-container>

            <ng-container matColumnDef="view">
                <th style="width: 5%" mat-header-cell *matHeaderCellDef> </th>
                <td mat-cell *matCellDef="let request">
                    <button class="add-view-button" mat-button (click)="view(request.id)">View</button>
                </td>
            </ng-container>

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

I know it's super simple, but I couldn't do it. I started to lose my nerves. The data from _holidayrequests is supposed to be displayed in mat-table and then later it is supposed to be sorted on click of column header.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source