Shijil Narayanan
Shijil Narayanan

Reputation: 1019

Facing issue while rendering index value of *ngFor directive in Angular 5

I am facing an issue while rendering index of *ngFor directive for a particular use case as follows.

Lets say we have an array of objects as

this.temp = [
  {name:'John',age:24,visibility:'visible',
  {name:'Kane',age:26,visibility:'hidden',
  {name:'Ross',age:28,visibility:'visible',
  {name:'Lui',age:21,visibility:'visible'
]

For rendering this in my app.component.html file I have html as follows

<div *ngFor="let user of temp; let i = index">
 <div *ngIf="user.visibility === 'visible' ">
    <div>{{i+1}}</div>
    <div>{{user.name}}</div>
 </div>
</div>

So as per the above array example, it renders users

1.John
2.Ross
3.Lui

Now there is a button name 'Change visibility' against each user in my UI, where in it will toggle the visibility state of user from 'hidden' to 'visible' and viceversa.

So clicking on button mentioned against John, it will set its visibility as hidden but the UI rendered is

2.Ross
3.Lui

My expected output is

1.Ross
2.Lui

How to make the index render properly ?

The use case here is that I cannot modify/alter my this.temp array in terms of length.Basically I need the entire array with only visiblity property changed in it as per user actions.

Please help.

Upvotes: 0

Views: 256

Answers (3)

Narendra Jadhav
Narendra Jadhav

Reputation: 10262

You can also achieve your required result by using Pipe like this

HTML component

<div *ngFor="let user of temp | visiblefilter ; let i=index">
    <span>{{i+1}} {{user.name}}</span> <button name={{user.name}} (click)="onHide($event)">Hide</button>
</div>

PIPE

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'visiblefilter',
    pure: false
})
export class VisibleFilterPipe implements PipeTransform {
    transform(items: any[]): any {
        return items.filter(({visibility}) =>visibility=='visible');
    }
}

You can check here with working example stackblitz

Upvotes: 1

user4676340
user4676340

Reputation:

use a custom trackby function :

*ngFor="let user of temp; let i = index; trackBy: customTB"

customTB(index, item) {
  return index + ' - ' item.name;
}

Upvotes: 0

Daniel Segura P&#233;rez
Daniel Segura P&#233;rez

Reputation: 1117

you can filter array first:

<div *ngFor="let user of temp.filter(us => us.visibility === 'visible'); let i = index">
 <div>
    <div>{{i+1}}</div>
    <div>{{user.name}}</div>
 </div>
</div>

like this way, you dont analize all array items too, more efficient and desired output.

Cheers!

Upvotes: 2

Related Questions