0
votes

I have been trying to filter mat-table by a specific column, in my case filter the table by the "date" column. But still it filters the table by all the columns. point me out what should I change or add in order to get the filtering work as expected.

.component.ts

import { Component, OnInit } from '@angular/core';
import {MatTableDataSource} from "@angular/material/table";
import {AllPlayedMatchesService} from "./all-played-matches.service";

export interface AllMatches {
  team1: string;
  team2: string;
  team1Score: number;
  team2Score: number;
  date: string;
}

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

  displayedColumns: string[] = ['club_1', 'club_2', 'club_1_score', 'club_2_score', 'date'];
  dataSource = new MatTableDataSource<AllMatches>();
  columns: string[];

  constructor(private tableService: AllPlayedMatchesService) { }

  ngOnInit(): void {
    this.tableService.getMatches().subscribe((data) => {
      this.dataSource = new MatTableDataSource<AllMatches>(data['response']);
      this.columns = data['response'].date;
    })

    this.dataSource.filterPredicate = function(data, filter: string): boolean {
      return data['response'].date.includes(filter);
    };
  }

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

}

.component.html

<h1>All Played Matches</h1>
<mat-form-field style="padding-right: 20px;">
  <mat-label>Enter date to search</mat-label>
  <input matInput (keyup)="applyFilter($event.target.value)" #input placeholder="eg: 26-12-2020">
</mat-form-field>

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

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


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


    <ng-container matColumnDef="club_1_score">
        <th mat-header-cell *matHeaderCellDef> CLUB 1 SCORE </th>
        <td mat-cell *matCellDef="let element"> {{element.team1Score}} </td>
    </ng-container>


    <ng-container matColumnDef="club_2_score">
        <th mat-header-cell *matHeaderCellDef> CLUB 2 SCORE </th>
        <td mat-cell *matCellDef="let element"> {{element.team2Score}} </td>
    </ng-container>


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

    <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    <tr class="mat-row" *matNoDataRow>
      <td class="mat-cell" colspan="4">No matches have been played on "{{input.value}}"</td>
    </tr>
</table>
</div>

It also says "value" is unresolved when I call applyFilter($event.target.value) function in HTML.

1

1 Answers

0
votes

you need move the instruction: this.dataSource.filterPredicate = function(data, filter: string): boolean... inside your subscribe function -after create the dataSource- futhermore, you has an error when define the function

this.tableService.getMatches().subscribe((data) => {
      this.dataSource = new MatTableDataSource<AllMatches>(data['response']);
      this.columns = data['response'].date;
      //move here
      this.dataSource.filterPredicate = (data:any, filter: string): boolean=> {
          //see that "data" here is the value of the "row"
          return data.date.includes(filter);
      };
    })

NOTE: I like arrow flat, but you can use also (I change the name of the argument of the function data by row)

      this.dataSource.filterPredicate = function (row:any, filter: string): boolean {
          return row.date.includes(filter);
      };