5

The trackBy function (e.g. in an ngFor) provides two arguments: index and item (from the collection being iterated over). Is there a way to pass additional information (as parameters?) to th trackBy function?

My case is that I might be iterating over a variety of types for each instance of my component (which contains the ngFor), with different identifying field names. Ideally, I'd like to be able to pass a third parameter indicating which field in my item should be read.

Sujatha Girijala
  • 1,141
  • 8
  • 20
skeej
  • 840
  • 1
  • 8
  • 23

2 Answers2

12

bind method can help you to do this trick

template.html

<div *ngFor="let item of items; trackBy: trackByFn.bind(this, 'name')">
  {{ item }}
</div>

component.ts

items = [
  {
    id: 1,
    name: 'name1'
  },
  {
    id: 2,
    name: 'name2'
  }
]
trackByFn(customParam, index, item) {
  return item[customParam];
}
yurzui
  • 205,937
  • 32
  • 433
  • 399
1

I know this question is over a year old now, but I'd like to add another option:

You can create an Angular pipe that takes the additional parameter(s) as arguments and returns a TrackByFunction. The use of such pipe would look as follows:

<div *ngFor="let item of items; trackBy: (myParameter | myTrackByFn)">

The code for the pipe looks as follows:

@Pipe({ name: 'myTrackByFn' })
export class MyTrackByFnPipe implements PipeTransform {

  transform<T>(myParameter: any): TrackByFunction<T> {
    return (index: number: item: T) => {
      // ...
    };
  }
}

One of the benefits that comes with this approach is that you can reuse the pipe across components, eliminating the need to reimplement a trackBy function in every component.

You can read more about this approach in Ben Nadel's post.

Sam Herrmann
  • 6,293
  • 4
  • 31
  • 50