Angular Material 2 DataSource filter with nested object

Here is a solution that incorporates recursion so you don't have to hard code each nested object or their key/value pairs.

this.dataSource.filterPredicate = (data, filter: string)  => {
  const accumulator = (currentTerm, key) => {
    return this.nestedFilterCheck(currentTerm, data, key);
  };
  const dataStr = Object.keys(data).reduce(accumulator, '').toLowerCase();
  // Transform the filter by converting it to lowercase and removing whitespace.
  const transformedFilter = filter.trim().toLowerCase();
  return dataStr.indexOf(transformedFilter) !== -1;
};

And the nestedFilterCheck

nestedFilterCheck(search, data, key) {
  if (typeof data[key] === 'object') {
    for (const k in data[key]) {
      if (data[key][k] !== null) {
        search = this.nestedFilterCheck(search, data[key], k);
      }
    }
  } else {
    search += data[key];
  }
  return search;
}

Thanks to @Sagar Kharche for the filterPredicate override.


This is a very generic solution and will work for sure. It does not depends on the structure of json, be it simple or nested, this solution works for all.

this.dataSource.filterPredicate = (data: any, filter) => { const dataStr =JSON.stringify(data).toLowerCase(); return dataStr.indexOf(filter) != -1; }