Search code examples
angularangular-materialmaterial-designmaterial-tableangular-material-table

Angular Material Table Sorting with reactive formarray


I am trying to implement sorting / filtering on angular material table with formArray as input data source.

StackBlits code link

dataSource = new MatTableDataSource([]);
<table mat-table [dataSource]="formdataarray.controls" multiTemplateDataRows class="mat elevation-z8" matSort >
<ng-container  matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay" >
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{column}}</th>
<td mat-cell *matCellDef="let element"> {{ element.value[column] }}  </td>
</ng-container>

But Sorting / Filtering is not working


Solution

  • You have two options here:

    • use plain array formdataarray.controls as a dataSource and implement all DataSource methods like filter, sort by your own. Or write custom CDK DataSource implementation. See also https://blog.angular-university.io/angular-material-data-table/

    • use MatTableDataSource and adjust filtering and sorting logic to support AbstractControl object.

    html

    <table mat-table [dataSource]="dataSource"
    

    ts

    ngOnInit() {
      // fill FormArray
      ...
      this.dataSource.data = this.formdataarray.controls;
      this.dataSource.sortingDataAccessor = (data: AbstractControl, sortHeaderId: string) => {
        const value: any = data.value[sortHeaderId];
        return typeof value === 'string' ? value.toLowerCase() : value;
      };
    
      const filterPredicate = this.dataSource.filterPredicate;
      this.dataSource.filterPredicate = (data: AbstractControl, filter) => {
        return filterPredicate.call(this.dataSource, data.value, filter);
      }
    }
    

    Forked Stackblitz

    Also, if you want to add new items to your FormArray you should update this.dataSource.data as well. See also Angular Material editable table using FormArray