why my filtering not working in mat table?

Issue

my filtering not working on my mat table. data comes from api but my code not working
I think my loaded information type has a problem with dual search functions getFormsValue() andformSubscribe

my api-service.service.ts is

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient }    from '@angular/common/http'

export interface Element {
  id: number;
  name: string;
  username: string;
  email: string;
}
@Injectable({
  providedIn: 'root'
})
export class ApiServiceService {
  constructor(private http: HttpClient ) { }
 getRandomUsers(): Observable<Element> {
  const URL = 'https://jsonplaceholder.typicode.com/users';
  return this.http.get<Element>(URL);
 }
}

and my persons.ts file in my code is

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup} from '@angular/forms'
import { FormControl, } from '@angular/forms'
import { MatTable, MatTableDataSource } from '@angular/material/table';
import {ApiServiceService,Element} from './api-service.service'
import { Subscription } from 'rxjs/internal/Subscription';
@Component({
  selector: 'app-persons',
  templateUrl: './persons.component.html',
  styleUrls: ['./persons.component.css']
})
export class PersonsComponent implements OnInit {
  private subs = new Subscription();
  private dataArray: any;
  dataSource = new MatTableDataSource<Element>()
  constructor(private financeService: ApiServiceService) { }
  displayedColumns: string[] = ['position', 'name', 'username', 'email','action'];

 // none value
 filterValues = {
  name: ''
};

// form group
filterForm = new FormGroup({
  name: new FormControl()
});

get name() {
  return this.filterForm.get('name');
}

  ngOnInit() {
    this.subs.add(this.financeService.getRandomUsers()
      .subscribe((res) => {
        console.log(res);
        this.dataArray = res;
        console.log(this.dataArray);
        this.dataSource = new MatTableDataSource<Element>(this.dataArray)
      },
       ));
       this.formSubscribe();
       this.getFormsValue();
  }

  // form subscribe
  formSubscribe() {
    if (this.name !=null){
    this.name.valueChanges.subscribe(nameValue => {
      this.filterValues['name'] = nameValue;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    });
  }
  }
  // create filter
  getFormsValue() {
    this.dataSource.filterPredicate = (data: any, filter: string): boolean => {
      let searchString = JSON.parse(filter);

      const resultValue =
        data.name.toString().trim().toLowerCase()
          .indexOf(searchString.name.toLowerCase()) !== -1;

      return resultValue;
    };
    this.dataSource.filter = JSON.stringify(this.filterValues);
  }
}

and my html file is bellow:

<form [formGroup]="filterForm">
  <div>
    <div class="form-group">

    </div>
    <div>
      <mat-form-field>
        <input matInput formControlName="name" placeholder="Enter name">
      </mat-form-field>
    </div>
  </div>
</form>

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

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

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


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

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



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

  <ng-container matColumnDef="action">
    <th mat-header-cell *matHeaderCellDef> Action </th>
    <td mat-cell *matCellDef="let element" class="action-link">
    </td>
  </ng-container>

   <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</mat-table>
<mat-paginator [length]="10" [pageSizeOptions]="[2,5, 7, 10]" aria-label="Select page">
</mat-paginator>

but my search with name not working
thanks for your help

Solution

The issue here is that you create a custom filter for MatTableDataSource but some time later you’re overriding existing dataSource with a new instance of MatTableDataSource but doesn’t patch the filter again.

this.subs.add(this.financeService.getRandomUsers()
  .subscribe((res) => {
      console.log(res);
      this.dataArray = res;
      console.log(this.dataArray);
      this.dataSource = new MatTableDataSource<Element>(this.dataArray);
      this.getFormsValue(); <========================================= add this
    },
  ));

Answered By – yurzui

Answer Checked By – Timothy Miller (AngularFixing Admin)

Leave a Reply

Your email address will not be published.