2

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.