Search code examples
javascriptdictionaryfiltereval

Alternative for using `eval()` - Filter products


I'm currently trying to build a filter system for within my software and this is what I have below, as you can see i'm using eval() and would like a solution where i don't need to use eval(), does anybody have any suggestions?

const items = [{
    Product: {
    name: 'Hello',
    which: 1
  },
  Finance: {
    zero: 0
  }
},
{
    Product: {
    name: 'Hello2',
    which: 0
  },
  Finance: {
    zero: 0
  }
}];

const filterMenu = [{
        name: 'text1',
        filterKey: 'Finance.zero == 0',
        subText: false
    }, {
        name: 'text3',
        filterKey: 'Product.which == 0',
        subText: false
}];

const filteredBy = [0, 1];

const filtered = items.filter(e => eval(filteredBy.map(item => "e." + filterMenu[item].filterKey).join(' && ')));
                 
console.log(filtered);


Solution

  • I'd suggest storing your filters as objects instead of strings. This way you can check each filterKey via the every() method.

    const items = [
      {
        Product: { name: 'Hello', which: 1 },
        Finance: { zero: 0 },
      },
      {
        Product: { name: 'Hello2', which: 0 },
        Finance: { zero: 0 },
    }];
    
    const filterMenu = [
      {
        name: 'text1',
        filterKey: { group: 'Finance', key: 'zero', value: 0 },
        subText: false,
      },
      {
        name: 'text3',
        filterKey: { group: 'Product', key: 'which', value: 0 },
        subText: false,
      }
    ];
    
    const filtered = items.filter(( item ) => {
      return filterMenu.every(( filter ) => {
        const { group, key, value } = filter.filterKey;
        
        return item[group][key] === value;
      });
    });
                     
    console.log(filtered);