Angular Multiple filters for Server level filtering using Mongoose model.find()

Viewed 250

I have a mat-table being displayed which has filtered data from server at any point in time. This is imp to note as for every filter or search a new data set is fetched from the server. I can not bring in the entire collection and manage filters in the front end as the collection can be huge - at least 8-10k records per year.

Need to give the users multiple filters(mat-selects) in addition to the existing search box(input).(pls see the screenshot)

As of now this is working ONLY with the Search input using the standard mat-table input search method with server side filtering. I need help to incorporate the additional filters.

component.ts: The component uses the below service method to get data from server in which I pass the filter string, sort info and paginator info.

this.serviceLogService.getServiceLog(
            this.input.nativeElement.value,
            this.sort.active,
            this.sort.direction,
            this.paginator.pageIndex,
            this.paginator.pageSize
          );

http call from service

getServiceLog(filter: string, sortKey: string, sortOrder: string, pageIndex: number, pageSize: number):
 Observable<{servicelogs: ServiceLog[], totalCount: number, servLogFilts: ServLogFilts }> {

    if (sortKey === '' || !sortKey) { sortKey = 'servNumber'};
    if (sortOrder === '' || !sortOrder) { sortOrder = 'desc'};

    return this.httpClient.get<{servicelogs: ServiceLog[], totalCount: number, servLogFilts: ServLogFilts}>(this.reqUrl, {
      params: new HttpParams ()
        .set('filter', filter)   // currently this refers to the search input
        .set('sortKey', sortKey)
        .set('sortOrder', sortOrder)
        .set('pageIndex', pageIndex.toString())
        .set('pageSize', pageSize.toString())
    });
  }

Currently I am using http Get request and sending the filter data as query params. But I guess with this additional 8 filters I will need to add a payload to the request and hence change the request to a Post request.

I want to use a filter object which can be used to filter data in the mongoose model find() query.

The backend server query would look something like below(not functional yet)

    docQuery = ServiceLog.find({
      $and: [
         $or: [
           { compName: { $regex:  filter, $options: 'i' } },
           { servName: { $regex:  filter, $options: 'i' } },
         ],
         $and: [
           { filt1Key: filt1Value },
           { filt2Key: filt2Value },
           ....
         ]
      ]
      }).collation({ locale: 'en'});

      ... sort and pagination applied on docQuery hereafter

I need to create that filter array for the inner $and. I am using the below method in component to create that array when Apply Filters button is clicked.

component method to create the filter array

  onApplyFilters(){
    let filtObj = [];
    if(this.form.value.filtFY) filtObj.push({ 'FY': this.form.value.filtFY}) ;
    if(this.form.value.filtServPeriod) filtObj.push({ 'servPeriod': this.form.value.filtServPeriod});
    if(this.form.value.filtDueMonth) filtObj.push({ 'dueMonth': this.form.value.filtDueMonth});
    if(this.form.value.filtCompCat) filtObj.push({ 'compCat': this.form.value.filtCompCat});
    if(this.form.value.filtServStatus) filtObj.push({ 'servStatus': this.form.value.filtServStatus});
    if(this.form.value.filtServCat) filtObj.push({ 'servCat': this.form.value.filtServCat});
    if(this.form.value.filtExecName) filtObj.push({ 'execName': this.form.value.filtExecName});
    if(this.form.value.filtPaytStatus) filtObj.push({ 'paytStatus': this.form.value.filtPaytStatus});

    console.log('filtObj:', filtObj)
    /// and hereafter call the service to in turn make an Http call
  }

But it gives me a complex array with proto etc. I need to create a simple array which may just look like this:

[
 { FY: 'xxxx' },
 { compCat: 'yyyy' }
 ...
]

And then I will pass this array as a variable for the inner $and in the above mongoose query.

How do I achieve this? And is this the optimal way to implement multiple filters to a data table.

enter image description here

0 Answers
Related