Is there another way to access an *ngFor item other than by its index

274 views Asked by At

I have an *ngFor list of food items (foods) that performs an animation when the user mouses over the element

<div [@foodState]="food.state" *ngFor="let food of foods; trackBy let i=index" (mouseenter)="open(i)" (mouseleave)="close(i)">

The open() and close() methods alter a property on the element called state

open(i: number): void{
  this.foods[i].state = 'open';
}

which triggers a new animation state

animations: [
  trigger('foodState', [
    state('closed', style({
      height: '36px'
    })),
    state('open', style({
      height: '58px'
    })),
  ])
]

The problem I'm facing is that I want to add a @Pipe to filter the data based on a search term:

<div [@foodState]="food.state" *ngFor="let food of foods| searchPipe: searchTerm; trackBy let i=index" (mouseenter)="open(i)" (mouseleave)="close(i)">

the @Pipe transforms the foods list using the filter() function:

transform(foods: any[], searchTerm: string): any[] {
  foods = foods.filter(food => food.name.toUpperCase().indexOf(searchTerm.toUpperCase()) !== -1 );
  return foods;
}

so now the index of the food, over which the user will hover, no longer corresponds to the correct food in the foods list.

Is there a way to trigger the state of a repeated item without accessing it through its original array index? Or is there another way that I should approach accessing data in *ngFor lists?

1

There are 1 answers

0
JayChase On BEST ANSWER

You can pass the food item itself instead of just the index:

 <div [@foodState]="food.state" *ngFor="let food of foods; trackBy let i=index" (mouseenter)="open(food)" (mouseleave)="close(food)">

and change the open and close methods as well:

open(food: any): void{
  food.state = 'open';
}