Home > Enterprise >  How to use a filter in Angular (Ionic) based on OpenApi?
How to use a filter in Angular (Ionic) based on OpenApi?

Time:11-09

Currently in my Ionic app I use ng2-search-filter to filter my data in the list. However, my goal is to filter in the backend and pass this filtered data to the frontend.

I use OpenApi 3.0 as interface for the backend and frontend. In this interface I have two methods:

  1. getAllCarports() (to get all carports).

  2. getCarportLocationsByIdAndName(carportNameAndExternalId: string) (to get the filtered carports).

My list-client-service.service.ts

public getAllCarports() {
    return this.service.getAllCarports();
}
public getCarportLocationsByIdAndName(carportNameAndExternalId: string){
    return this.serviceFilter.getStructureCarportsByIdAndName(carportNameAndExternalId);
}

My current searchbar:

<ion-searchbar
    [(ngModel)]="searchTerm"
    showCancelButton="focus"
    animated>
</ion-searchbar>

My current list:

<ion-list id="list">
    <ion-item id="list-item" button *ngFor="let carport of carports | orderByCarportName | filter: searchTerm
              | paginate: {itemsPerPage: 8, currentPage: cp}"  class="listMargin" (click)="openCarport(carport.id)">
        <ion-label>{{carport.id}}</ion-label>
        <ion-label>{{carport.carportName}}</ion-label>
    </ion-item>
</ion-list>

When loading the page, the complete list should be returned as usual (getAllCarports()). But if you enter something in the searchbar then the method getCarportLocationsByIdAndName(carportNameAndExternalId: string) should be executed. Preferably the list should be updated again and again while typing. Does anyone have a solution or an approach? So far I have not found anything suitable on the web.

UPDATE 1

@Query("SELECT d FROM CarportLocationEntityView d WHERE d.externalId LIKE %:filterCriteria% OR lower(d.carportName) LIKE lower(concat('%', :filterCriteria,'%')) ")
List<CarportLocationEntityView> filterCarportList(@Param("filterCriteria") String filterCriteria);

UPDATE 2

<ion-searchbar (ionChange)="onChange($event)"
                        [(ngModel)]="filterTerm"
                        showCancelButton="focus"
                        animated>
</ion-searchbar>

<ion-row>
   <ion-col size="12">
       <ion-list id="list">
         <ion-item id="list-item" button *ngFor="let carport of carports | orderByCarportName 
              | paginate: {itemsPerPage: 8, currentPage: cp}"   (click)="openCarport(carport.id)">
          <ion-label>{{carport.id}}</ion-label>
          <ion-label>{{carport.carportName}}</ion-label>
         </ion-item>
       </ion-list>
     </ion-col>
</ion-row>
onChange(event) {
    const filterTerm = event.target.filterTerm
    if (filterTerm === '') {
      this.listClientService.getAllCarportNamesWithId()
    } else {
      this.listClientService.getCarportLocationsByIdAndName(filterTerm)}

CodePudding user response:

First of all since both Methods load a list carports, you should combine them. Just add parameters and if they aren't set (null) load all, otherwise filter accordingly. This could look like below

openapi example

Instead of ngModel, to react on input changes of your ion-searchbar you can hook onto ionics ionChange and simply send a request there. With the response overwrite the carport array (the ones used here *ngFor="let carport of carports) you hold in you .ts file.

The list will update while typing because you overwrite the array on every finish of the request. Be aware that you should debounce otherwise you will spam your backend unnecessarily.

Update1
If you can't update the backend just use the correct api call for the given searchbar input value.

<ion-searchbar (ionChange)="onChange($event)" ... </ion-searchbar>
onChange(event) {
    // log "event", it should be an object which contains the value of the searchbar but i'm unsure of it's properties rn
    const value = event.target.value // not 100% sure if correct
    if (value === '') {
        getAllCarports()
    } else {
        getCarportLocationsByIdAndName(value)
    }
}

Update2
Create an observable in your ts file and assign the result of your carport service to it.

carports: Observable<Carports[]>; // use the type that is returned by the service

... {
    ...
    this.carports = this.listClientService.getAllCarportNamesWithId()
}

use the keyword async for carports to signal that this will be loaded asynchronously and will update.

*ngFor="let carport of carports | async ...
  • Related