'Angular Material Table filtering not refreshing

I have an Angular Material table...

<div class="card">
  <div class="card-header">
    <b>{{ pageTitle }}</b>
  </div>

  <div class="card-body">
    <div class="table-responsive">
      <mat-button-toggle-group
        name="timecardStatus"
        id="timecardStatus"
        aria-label="Timecard Status"
        #timecardStatus="matButtonToggleGroup"
      >
        <mat-button-toggle
          value="5"
          (change)="onValChange($event.value)"
          checked
          class="timecardStatusBtn"
          >Submitted</mat-button-toggle
        >
        <mat-button-toggle
          value="7"
          (change)="onValChange($event.value)"
          class="timecardStatusBtn"
          >Approved</mat-button-toggle
        >
      </mat-button-toggle-group>
      <mat-table
        #table
        id="timecardManagementTable"
        mat-table
        [dataSource]="dataSource"
        matSort
        class="mat-elevation-z8"
      >
        <!-- <ng-container matColumnDef="name">
          <mat-header-cell *matHeaderCellDef mat-sort-header>
            Name
          </mat-header-cell>
          <mat-cell *matCellDef="let submittedTimecard">
            <span *ngIf="submittedTimecard.status === 5">
              {{ submittedTimecard.name }}
            </span>
          </mat-cell>
        </ng-container> -->
        <ng-container matColumnDef="beginPeriodDate">
          <mat-header-cell *matHeaderCellDef mat-sort-header>
            Beginning Date
          </mat-header-cell>
          <mat-cell *matCellDef="let submittedTimecard">
            <span *ngIf="submittedTimecard.status === 5">
              <a
                [routerLink]="[
                  '/',
                  clientId,
                  'timecardManagement',
                  submittedTimecard.id,
                  'details'
                ]"
              >
                {{ submittedTimecard.beginPeriodDate | date }}
              </a>
            </span>
            <span *ngIf="submittedTimecard.status === 7">
              {{ submittedTimecard.beginPeriodDate | date }}
            </span>
          </mat-cell>
        </ng-container>
        <ng-container matColumnDef="endPeriodDate">
          <mat-header-cell *matHeaderCellDef mat-sort-header
            >Ending Date</mat-header-cell
          >
          <mat-cell *matCellDef="let submittedTimecard">
            {{ submittedTimecard.endPeriodDate | date }}
          </mat-cell>
        </ng-container>
        <ng-container matColumnDef="totalHours">
          <mat-header-cell *matHeaderCellDef mat-sort-header
            >Total Hours</mat-header-cell
          >
          <mat-cell *matCellDef="let submittedTimecard">
            {{ submittedTimecard.totalHours | number: "1.2-2" }}
          </mat-cell>
        </ng-container>
        <ng-container matColumnDef="totalEarnings">
          <mat-header-cell *matHeaderCellDef mat-sort-header>
            Total Earnings
          </mat-header-cell>
          <mat-cell *matCellDef="let submittedTimecard">
            {{
              submittedTimecard.totalEarnings | currency: "USD":"symbol":"1.2-2"
            }}
          </mat-cell>
        </ng-container>
        <ng-container matColumnDef="approve">
          <mat-header-cell *matHeaderCellDef></mat-header-cell>
          <mat-cell *matCellDef="let submittedTimecard">
            <button
              class="btn btn-outline-success"
              type="button"
              title="Approve this Timecard"
              (click)="approveTimecard(submittedTimecard.id)"
              *ngIf="submittedTimecard.status === 5"
            >
              Approve
            </button>
            <button
              class="btn btn-outline-warning ml-3"
              type="button"
              title="Reject this Timecard"
              (click)="rejectTimecard(submittedTimecard.id)"
              *ngIf="submittedTimecard.status === 7"
            >
              Reject
            </button>
          </mat-cell>
        </ng-container>
        <mat-header-row
          *matHeaderRowDef="displayedColumns; sticky: true"
        ></mat-header-row>
        <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
      </mat-table>

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

When the approve button is clicked, the approveTimecard method runs...

approveTimecard( submittedTimecardId: string ) {
    this._timecardManagementService.approveTimecard( submittedTimecardId )
      .subscribe(
        ( dataTimecardApproved: any ) => {
          if ( dataTimecardApproved === 7 ) {
            return this._timecardManagementService.getSubmittedTimecards()
              .subscribe(
                timecardResponse => {
                  this.dataSource = new MatTableDataSource( timecardResponse );
                  this.onValChange( '5' );
                },
                err => {
                  console.error( err );
                }
              );
          }
        },
        ( err: any ) => console.log( err )
      );
  }

I am using this line to refresh the table datasource...

this.dataSource = new MatTableDataSource( timecardResponse );

I am using this line to "re-filter" the view...

this.onValChange( '5' );

Here is the onValChange method...

onValChange( filterValue: string ) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
    if ( this.dataSource.paginator ) {
      this.dataSource.paginator.firstPage();
    }
  }

Here is the issue...the table is not refreshing and refiltering. When I click the approve button, the method runs but the table does not refresh. What should happen is the item where I have clicked approve should no longer display in the filtered view. So what am I missing?



Solution 1:[1]

It will work only if u update the length property of mat-paginator. Try setting the length by [length]="dataSource.filteredData?.length || 0"

 <mat-paginator class="m-t-20" style-paginator [showTotalPages]="PAGINATION.showPageCount"
    [length]="dataSource.filteredData?.length || 0" [pageSize]="PAGINATION.defaultPageSize" [source]="dataSource">
  </mat-paginator>

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 Jobelle