Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the count of items in an ngFor after the pipes have been applied

I have an ngFor creating rows in a table that is both filtered and paged.

<tr *ngFor="#d of data.results | filter:filterText | pagination:resultsPerPage:currentPage"> 

There is another element on the page that displays the number of records displayed. These elements are initially bound to the data.Results' length.

How do I get the length of the data that is displayed after the filter pipe has been applied so that I can display it correctly. None of the provided local variables in ngFor seem to account for this.

like image 523
ghawkes Avatar asked Mar 17 '16 23:03

ghawkes


2 Answers

One way is to use template variables with @ViewChildren()

<tr #myVar *ngFor="let d of data.results | filter:filterText | pagination:resultsPerPage:currentPage"> 
@ViewChildren('myVar') createdItems;  ngAfterViewInit() {   console.log(this.createdItems.toArray().length); } 
like image 197
Günter Zöchbauer Avatar answered Sep 18 '22 08:09

Günter Zöchbauer


I found the simplest solution to be the following:

  1. In your component: add a field that will hold the current count
  filterMetadata = { count: 0 }; 
  1. In your template: add the filterMetadata as a parameter to the filter pipe
  <tr *ngFor="#d of data.results | filter:filterText:filterMetadata | pagination:resultsPerPage:currentPage"> 
  1. interpolate filterMetadata.count into the element that displays the number of records displayed.
  <span> {{filterMetadata.count}} records displayed</span> 
  1. In the filter pipe, update the filterMetadata.count field when done with filtering
  transform(items, ..., filterMetadata) {     // filtering     let filteredItems = filter(items);      filterMetadata.count = filteredItems.length;     return filteredItems;   } 

This solution still uses pure pipes, so there are no performance degradations. If you have multiple pipes that do filtering, the filterMetadata should be added as a parameter to all of them because angular stops calling the pipe sequence as soon as the a pipe returns an empty array, so you can't just add it to the first or last filtering pipe.

like image 29
Soufiane Sakhi Avatar answered Sep 19 '22 08:09

Soufiane Sakhi