ItFreak
ItFreak

Reputation: 2369

Angular 7 filter array

I have the following Angular component:

  private json: JsonResponseDTO;

  constructor(private dtoService: PoolDTOServiceService) {
  }

  ngOnInit() {
    this.dtoService.setJsonResponse();
    this.getPool();
  }

  getPool() {
    this.json = this.dtoService.jsonResponse;
  }

The json contains an element pools, that is an array. This one should be filtered by name, which is typed in an input. (I don not show the HTML, since this is not relevant).
I want to be able to 'remove' my search criteria, so the initial approach is:

  private json: JsonResponseDTO;
private filterJson: JsonResponseDTO;

  constructor(private dtoService: PoolDTOServiceService) {
  }

  ngOnInit() {
    this.dtoService.setJsonResponse();
    this.getPool();
  }

  getPool() {
    this.json = this.dtoService.jsonResponse;
    this.filterJson = this.json;
  }

  filter(filterCriteria: String) {
    this.filterJson = this.json;
    this.filterJson.pools.filter((element) => element.name === filterCriteria);
  }

and then bind the filterJson to the HTML DOM.
Is there a cleaner way to do this? I want to avoid requesting the new JSON each time the filtered name is 'removed', since the data is expensive in time to fetch.

Upvotes: 2

Views: 12044

Answers (2)

Akshay Rajput
Akshay Rajput

Reputation: 2078

You can use a pipe for filtering it will be much cleaner, just add the pipe in front of *ngFor directive.

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  transform(value: any, field: string, input: string) {
    if (input !== undefined && input.length >= 2) {
      input = input.toLowerCase();
      if (typeof value[0] === 'string') {
        return value.filter(function(el: any) {
          return el.toLowerCase().indexOf(input) > -1;
        });
      }
      return value.filter(function(el: any) {
        return el[field].toLowerCase().indexOf(input) > -1;
      });
    }
    return value;
  }
}

Add this pipe, and in HTML where ever you need to filter

<div *ngFor="let val of filterJson | filter: "filterCriteria""> </div>

from change detection and performance point of view, pipes are awesome. Hope this helps, all the best

Upvotes: 3

Dhananjai Pai
Dhananjai Pai

Reputation: 6005

filter(filterCriteria: String) {
    this.filterJson = {...this.json, pools: pools.filter((element) => element.name === filterCriteria);
}

You could potentially write it a bit cleaner by using spread and changing the pools property as above.

I'm assuming you should keep a cached copy of the original 'this.json' for a case when the filters are reset.

Upvotes: 1

Related Questions