ReactJs: Filtering nested objects

How do I filter nested objects in React? Currently my function is only looking for the main title, not the nested ones.

export const treeData = [
  {
    title: 'Orange',
    key: '0-0',
    children: [
      {
        title: 'Anu',
        key: '0-0-0',
        isLeaf: true,
      },
      {
        title: 'Anurag',
        key: '0-0-1',
        isLeaf: true,
      },
    ],
  },
  {
    title: 'ABC',
    key: '0-1',
    children: [
      {
        title: 'leaf 1-0',
        key: '0-1-0',
        isLeaf: true,
      },
      {
        title: 'leaf 1-1',
        key: '0-1-1',
        isLeaf: true,
      },
    ],
  },
]

export default {
  treeData,
}

and the function is:

 const filtered = treeData.filter((data) => {
      return data.title.toLowerCase().includes(e.target.value.toLowerCase())
    })

So currently it is only searching the Orange and ABC, not the titles from children.

Answer

I recommend flattening the title values and then filtering. Note, the end result will contain a mixture of top level “parent” data and children.

const flattened = treeData.reduce((acc, data) => {
  acc.push(data, ...data.children)
  return acc;
}, []);

const filtered = flattened.filter((data) => {
  return data.title.toLowerCase().includes(e.target.value.toLowerCase())
})

If you only need a filtered list of top level data, you will need to do something like the following:

function dataIncludesTitle(data, title) {
  return data.title.toLowerCase().includes(title);
}

const searchValue = e.target.value.toLowerCase();
const filtered = treeData.filter((data) => {
  return dataIncludesTitle(data, searchValue) || data.children.some(child => dataIncludesTitle(child, searchValue));
})