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.
