angularangular-material

How to add loader in mat-table in angular


Code:

 <table  mat-table [dataSource]="dataSource" matSort class="table table-responsive">
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
                  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
                 
                   
                  <tr class="mat-row" *matNoDataRow>
                    <td class="mat-cell" [attr.colspan]="displayedColumns.length">
                      No data to dislay.
                    </td>
                  </tr>
                </table>

here i added this for empty data but is there any functionality for loading ?? i am getting that data from api so its take some time. if response data is empty then my above code work fine but i want same thing with loader


Solution

  • I would assume nothing, since the context of loader isnt clear. first you will have to modify your.ts file. Although you would have to change the datatype "any" to the desired type

    import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable, of, catchError, map, startWith } from 'rxjs';
    
    @Component({
      selector: 'app-your-component',
      templateUrl: './your-component.component.html',
      styleUrls: ['./your-component.component.css']
    })
    export class YourComponent implements OnInit {
      data$: Observable<any[]> = of([]);
      loading$: Observable<boolean> = of(true);
    
      displayedColumns: string[] = ['column1', 'column2', 'column3'];
    
      constructor(private http: HttpClient) { }
    
      ngOnInit() {
        this.data$ = this.http.get<any[]>('your-api-endpoint').pipe(
          map(data => {
            this.loading$ = of(false);
            return data;
          }),
          startWith([]), // Emits an empty array initially
          catchError(() => {
            this.loading$ = of(false);
            return of([]);
          })
        );
      }
    }
    

    Then you will have to update your html file with this.

        <table mat-table [dataSource]="data$ | async" matSort class="table table-responsive">
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    
      <!-- Loader Row -->
      <tr *ngIf="(loading$ | async)" class="mat-row">
        <td class="mat-cell" [attr.colspan]="displayedColumns.length" class="loading-cell">
          <mat-spinner></mat-spinner>
        </td>
      </tr>
    
      <!-- No Data Row -->
      <tr *ngIf="!(loading$ | async) && (data$ | async)?.length === 0" class="mat-row">
        <td class="mat-cell" [attr.colspan]="displayedColumns.length">
          No data to display.
        </td>
      </tr>
    </table>
    

    You can use this code as an alterate for putting the spinner in the table.

    </td>
    <td class="mat-cell" [attr.colspan]="displayedColumns.length" *ngIf="isLoading">
    <mat-spinner diameter="50"></mat-spinner>
    </td>
    </tr>
    

    // this is an extra if you want to style the container with css

    .loader-container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
    }