0
votes

In my angular 7 application, I use keyvalue filter to take key and value. Here, I need to filter the value which gives by the user. I have created the custom pipe and send the sample the same response what I have received from the API, but it does not work.

Anyone help me to do this?

JSON GET IT FROM SERVER

addedAirport = [[
{
  "2": [
    {
      "airportId": 33,
      "name": "Montreal-Mirabel International Airport",
      "countryId": 2,
      "stateId": 45,
      "city": null
    },
    {
      "airportId": 34,
      "name": "Montreal-Pierre Elliott Trudeau International Airport",
      "countryId": 2,
      "stateId": 45,
      "city": null
    }
  ]
}]]

.html (angular view)

<div class="airport-row row" *ngFor="let country of addedAirport[0]  | keyvalue | searchFilterAirportBy: ['name']: searchAirport;  let in = index; ">
   {{country.key}} // Here I called one more function to take name of the country
 <div class="selection-row airport-selection row" *ngFor="let airport of country.value;  let inAirport = index; ">
   {{airport.name}}
 </div>
</div>

PIPE

transform(list: any, prop: string, substring: string) {
    // console.log(list);
    if (substring.length > 0) {
        const newList: any = [{
            '2': [
            {
                'airportId': 33, 
                'name': 'Montreal-Mirabel International Airport', 
                'countryId': 2,
                'stateId': 45,
                'city': null
            },
            {
                'airportId': 34,
                'name': 'Montreal-Pierre Elliott Trudeau International Airport',
                'countryId': 2,
                'stateId': 45,
                'city': null
            }
        ]
        }];

return newList; ......

Note: Normaly, I can see the data as { "key": "2", "value":...}. But, after I sent from Pipe, it shows as normal as { "2": [ { "airportId": 33, "name": " ...}

Anyone help me how to pass the data as key and value from pipe ?

1
You should probably try to avoid creating this type of filtering pipe as it can have immensely negative performance issues. angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe . Instead do this filtering in the component or a service. - Alexander Staroselsky

1 Answers

0
votes

As the filter is going to return the data in the same shape as the service response (i.e. an array of maps), better to apply the filter first and then transform each map object into its country array using keyvalue.

<ng-container
        *ngFor="let mapObj of addedAirport[0] | searchFilterAirportBy: ['name']: searchAirport">
    <div class="airport-row row"
         *ngFor="let country of mapObj | keyvalue ; let in = index; ">
        {{country.key}}
        <div class="selection-row airport-selection row"
             *ngFor="let airport of country.value;  let inAirport = index; ">
            {{airport.name}}
        </div>
    </div>
</ng-container>

However note that it is not recommended to apply filters or sorts on ngFor due to performance issues.