Reputation: 1019
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
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
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
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