0

I'm trying to filter a grid using multiple filters of various types (boolean, string match, etc.). The grid is just a JSON array. I have to filter every time a filter value is set or removed (i.e. a checkbox is checked, or unchecked). I was trying to do this using a very complex switch statement, but then I found this post by @ori-drori which explains how to do this using a much simpler map of filterHandlers. However, when I run this code I don't get the desired results and I'm stumped as to why. Here's what I've got:

filterGrid(rows) {
   const filterList = [
     { 'open': this.onlyOpen },
     { 'assmtComplete': this.onlyAssmtCompleted },
     { 'bureau': this.selectedBureau ? this.selectedBureau : '' },
     { 'unit': this.selectedUnit ? this.selectedUnit : '' }
   ];
   const filterHandlers = new Map([
     [
      'open',
      (ref) => !ref.cwsClosureReasonDescription
     ],
     [
      'assmtComplete',
      (ref) => ref.safetyAsstComplDate !== null
     ],
     [ 
      'bureau', 
      (ref, val) => ref.bureauCode === val 
     ],
     [ 
      'unit', 
      (ref, val) => ref.unitID === val 
     ],
   ]);

   const applyFilters = (arr, filters) => {
      const filterKeys = Object.keys(filters);  
      return arr.filter(o => filterKeys.every((key) => {
        const handler = filterHandlers.get(key);  // THIS returns undefined every time
        return !handler || handler(o[key], filters[key]);
      }));
   };

   const result = applyFilters(rows, filterList);
   console.log(result);
 }

A sample object in the "rows" might look like this:

{
   createdDate: "2019-10-18T10:56:43.477"
   closureReasonDescription: null
   refNumber: "1231-3213-2132-1321321"
   incidentZipCode: "92108"
   intakeDate: "2019-10-19T00:56:24.953"
   referralId: 1461
   bureauCode: "S"
   unitID: 1017
   safetyAsstComplDate: null
   taskTypeId: null
}

As you can see from the comment in the code above, that line in the applyFilters is always undefined. I've tried a few ways of getting the handler from that, but I'm not sure what key is supposed to be - an integer or a string? Any tips would be GREATLY appreciated!

3
  • A key is the name of a property in the object, so "createdDate" in your example. Commented Oct 21, 2019 at 17:56
  • Right, that's what I thought, but the line "const filterKeys = Object.keys(filters);" returns an array of strings, which are actually just the index of each filter (i.e. ["0","1","2","3"]). It should return this though: ["open","assmtComplete","bureau","unit"], right? So how do I get the correct keys? Thanks Commented Oct 21, 2019 at 18:02
  • For Object.keys to work, filterList needs to be defined like this const filterList = { open: this.onlyOpen, assmtComplete: this.onlyAssmtCompleted, etc...}; Commented Oct 21, 2019 at 18:03

1 Answer 1

1

filterKeys (defined by Object.keys(filterList)) is an array of numeric keys (["0", "1", "2", "3"]) since filterList is an array whose keys are numeric indices.

I think you want filterKeys to be the keys of each object in the filterList array. This could be achieved most easily by making filterList a single object, with many keys, instead of an array of objects with one key each:

const filterList = {
    'open': this.onlyOpen,
    'assmtComplete': this.onlyAssmtCompleted,
    'bureau': this.selectedBureau ? this.selectedBureau : '',
    'unit': this.selectedUnit ? this.selectedUnit : ''
];
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, you're right, it should be an object with keys. I made that change, and now it's grabbing the correct filter to compare each record against. Thank you!

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.