Search code examples
javascriptangulartypescripteventemitter

Building an API Call Holding Multiple Filter-selected Values in Angular App


I have a series of checkbox filters in my Angular app, that when clicked on by a user in the view, should trigger functionality that queries the API to return filtered results. I have these filters working when used one at a time. However, I'm having difficulty figuring out how to structure the function so that it can hold ALL currently selected filters. The function call makes use of a Mongoose/MongoDB feature that lets us pass key/value pairs that correspond to fields directly into the payload of a post request.

This is what I initially had (that works, but only by handling one filter at a time via if/else statements). It basically says, if the "type" is of "lan", then assign value accordingly. And if no value is provided (i.e. the user has de-selected all filters), then just send an API call request without including any inputed parameters (the last "else" here):

    onFilterReceived(value, type) {
        if (type === 'lan' && value) {
            this.filtersService.getByFilter(this.page, this.pagesize, {
                "services.workflow.status" : "consulting",
                "languages.primary" : { $in: value }
                });
        } else if (type === 'zip' && value) {
            this.filtersService.getByFilter(this.page, this.pagesize, {
                "services.workflow.status" : "consulting",
                "zipCode" : { $in: value }
                });
        } else {
            this.filtersService.getByFilter(this.page, this.pagesize, {
                "services.workflow.status" : "consulting"
            });
    }

I am getting both "value" and the corresponding "type" sent via Angular's Output() and EventEmitter(), like this:

        <list [records]="records"
            (sendLanguage)="onFilterReceived($event, type = 'lan')"
            (sendZipcode)="onFilterReceived($event, type = 'zip')">
        </list>

Again, all of the above works as is.

However, what I'm trying to do is build this function is such a way that, when the value received is of type "lan", that the corresponding "value" in that case is applied to "value" here:

"languages.primary" : { $in: value }

And then when the value received has a corresponding type of "zip", that "value" is then applied to "value" here:

"zipCode" : { $in: value }

The end goal being that I will be able to send a request over the API that holds the values of multiple filters AT THE SAME TIME.

I've tried numerous formulations, but so far have been unable to get this to work as desired. I've been using 'if/else' statements, like above, but again, that will only allow me to hold a value from one filter at a time. How could I make sure I'm passing each of the currently selected filter values?

If someone could provide even a basic example of how to formulate this kind of logic, it'd be very helpful.


Solution

  • body: any = {'services.workflow.status':'consulting'};
    
    private processType(name: string, para: any) {
        if (this.body[name]) // toggle filter, removing or adding
            delete this.body[name];
        else
            this.body[name] = { $in: para };
    }
    
    onFilterReceived(para: any, type: string) {
        if (type == 'lan') {
            this.processType('languages.primary', para);
        }
        if (type == 'zip') {
            this.processType('zipCode', para);
        }
        if (type == 'nat') {
            this.processType('services.service', para);
        }
        console.log(this.body);
    
        this.filtersService.getByFilter(this.page, this.pagesize, this.body)
            .subscribe(resRecordsData => {
                           this.records = resRecordsData;
                       },
                       responseRecordsError => this.errorMsg = responseRecordsError
            );
    }