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
  • 953
  • 7
  • 20
skeej
  • 802
  • 1
  • 8
  • 23

2 Answers2

10

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
  • 171,085
  • 24
  • 365
  • 354
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
  • 4,201
  • 3
  • 18
  • 36