[Table] Support sorting / filtering table with pipes
See original GitHub issueBug, feature request, or proposal:
Request
What is the expected behavior?
I use the MatTable
feature.
My data source contains a bunch of ids, so most of my columns is bound to an id property and use a pipe to display the name.
For example:
<ng-container matColumnDef="type"> <th mat-header-cell *matHeaderCellDef> Type </th> <td mat-cell *matCellDef="let device"> {{product.TypeId | productTypePipe}} </td> </ng-container>
And it works great!
However when I wanted to implement sort or filter I stumble some difficulties.
Apparently the table uses the model to sort / filter data.
However I wish to sort the table using the piped value and not the id value.
Likewise, I would like to filter by the piped value (which are strings) and not the ids (which the client is not aware of).
For the sorting issue I tried to use the sortingDataAccessor
however I couldn’t use the services that translate the ids into names. (I guess because the context is different)
What is the current behavior?
the current behavior uses the model given to the DataSource with no regard to what actually displayed in the table.
What are the steps to reproduce?
https://angular-material2-issue-m3sdhq.stackblitz.io (Try to sort the symbol column)
Manual reproduce
- Create a pipe that translates a number to a string.
- create table that the cell uses this pipe.
- try to sort / filter by the value name.
What is the use-case or motivation for changing an existing behavior?
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Angular: Angular 6. OS: Windows 7 TypeScript: 2.7.2. Browsers: Chrome (But I believe every browser is affected)
Is there anything else we should know?
My pipes uses DI so I can just create instance of them (I wish I could)
Thanks
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:15
Top GitHub Comments
Modifying the data model to transform the data in the component comes with its own set of problems when using a Material Table.
For example, piping a Date using a DatePipe, shortDate format in the component code outputs a string in M/d/yy format. If the user then clicks the column header above the date field to sort, it will sort alphabetically rather than chronologically because it’s a string and not a date.
Letting the true date exist in the data model, but still transforming it HTML-side using a DatePipe allows the data to display in a human-friendly format, and the sort to work as one would expect.
Unfortunately, the filter being tied to that same data model does not create an expected filtering behavior, as the user is filtering data that they may not be able to see (a true date rather than a formatted string).
@leongrin I’ll try one more time to illustrate what I mean. In your code, you would change the transform method in your pipe as follows:
Then in your template, you would pass in the whole row object to the pipe:
Then somewhere in your component, you would set the sorting data accessor:
EDIT: This does not work correctly if the table is paginated and there is more than one page of results - see https://github.com/angular/components/issues/11782#issuecomment-545647745.