lwin
lwin

Reputation: 4460

Show filter result count in angular dynamically

I am new to angular and I using angular10.I have one array =>

 var test =  [
    {
        id:1,
        type:"banana",
        isgood:true
    },
    {
        id:1,
        type:"apple",
        isgood:false
    },
    {
        id:1,
        type:"waterml",
        isgood:true
    }    
]

I would like to show count of isgood==false in html.

example => Good Fruit Count : 2. How can I show like that?

One problem is this isgood is can change dynamically or runtime.So if I write method and show result in view, I will need to call this method every time I update this value.

So I would to do like that => If I want to show total count of array, I use like that {{test.length}}. Can I do like that => {{test.filter(f=>f.isgood===true).length}}?

Upvotes: 0

Views: 773

Answers (3)

Eldar
Eldar

Reputation: 10790

You can use a getter that returns the count and use that getter in the template like below :

import { Component } from "@angular/core";

@Component({
  selector: "my-app",
  template: `
    <hello name="{{ name }}"></hello>
    <button (click)="randomize()">Randomize</button>
    <div>
      <ul>
        <li *ngFor="let item of test">
          {{ item.type }} {{ item.isgood ? "is good" : "is meh" }}
        </li>
      </ul>
    </div>
    <div>Count of good : {{ goodsCount }}</div>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular";
  test: any[];
  get goodsCount() {
    console.log("called");
    return this.test.filter(r => r.isgood).length;
  }
  ngOnInit() {
    this.test = [
      {
        id: 1,
        type: "banana",
        isgood: true
      },
      {
        id: 1,
        type: "apple",
        isgood: false
      },
      {
        id: 1,
        type: "waterml",
        isgood: true
      }
    ];
  }
  randomize() {
    const randomIndex = (Math.random() * (this.test.length - 1)).toFixed(0);
    this.test[randomIndex].isgood = !this.test[randomIndex].isgood;
  }
}

Stackblitz

Upvotes: 1

MoxxiManagarm
MoxxiManagarm

Reputation: 9124

Function calls or filtering pipes in a template are not a good practice. The better way would be a reactive way using subject and rxjs.

fruits$: BehavioSubject<Fruit[]> = new BehaviorSubject<Fruit[]>([]);
goodFruitCount$: Observable<number> = this.fruits$.asObservable().pipe(
  map(fruits => fruits.filter(fuit => fruit.isgood).length),
);

Then you say in template Good fruits: {{ goodFruitCount$ | async }}

Every change to the fruits array is a next call on the subject

Upvotes: 1

The Fabio
The Fabio

Reputation: 6250

you could do a filter then lengthon he result:

count = test.filter(item => item.isgood === false).length

and to place it on html:

{{ test.filter(item => item.isgood).length }}

Upvotes: 1

Related Questions