Today I stumbled over the issue that I wanted to pass a custom trackBy function to an datatable which uses the function to generate custom track IDs for my custom data set. I am passing a custom function to my datatable which returns my custom IDs:
myCustomTrackByFn: Function = (index: number, row: MyRowElement): string => {
return row ? `${row.id1}_${row.id2}` : undefined;
};
<data-table [trackByFn]="myCustomTrackByFn"></data-table>
Well I thought now I can easily write my trackBy
function in the datatable:
trackRowBy(index: number, row: any): any {
if (this.trackByFn) {
return this.trackByFn(index, row);
} else {
// tracking a row by its object representation is the angular default
return row;
}
}
Unexpectedly this did not work. While debugging, I found out that the scope of this function was the angular differ (s. https://angular.io/api/core/TrackByFunction).
The solution was easier than expected: You can easily bind the components context to the trackBy function by using JS bind function:
<div *ngFor="let row of myRows; trackBy: trackRowBy.bind(this)">
{{row.id}} - {{row.title}}
</div>
Now the scope of this in our trackBy function is our component and we can use the passed trackBy function to get the rows’ IDs.
EDIT: after a bit of research I found this angular issue which exactly describes my solution with bind()
function: https://github.com/angular/angular/issues/14478