Hi freeCodeCamp fam
This has been driving me mad nearly all day, if anyone could validate this I’d muchly appreciate.
Ok, so the setup is, I have a Gatsby site with an index page and some data, the data looks a lot like this:
const data = [
{
frontmatter: {
title: 'Alfred',
},
headings: [
{
value: 'Add custom search',
depth: 2,
},
{
value: 'Change the default search in Alfred',
depth: 2,
},
],
fields: {
slug: '/alfred/',
},
},
{
frontmatter: {
title: 'Fish Shell',
},
headings: [
{
value: 'Aliases',
depth: 2,
},
{
value: 'Oh My Fish',
depth: 2,
},
{
value: 'Use nvm with fish',
depth: 2,
},
{
value: 'List out added aliases',
depth: 2,
},
],
fields: {
slug: '/fish/',
},
},
{
frontmatter: {
title: 'Bash',
},
headings: [
{
value: 'Add an alias',
depth: 2,
},
{
value: 'Sort alphabetically 👌',
depth: 2,
},
{
value:
'Open the SSH agent each time you open a new terminal.',
depth: 2,
},
],
fields: {
slug: '/bash/',
},
},
];
I’m trying to do a fuzzy search, which I’ve partially achieved on the slug
and title
fields it’s just this value
field in the headings array that’s driving me loopy!
function filterData(data, filters = {}) {
const defaults = {
fields: { slug: null },
frontmatter: { title: null },
headings: { value: null },
};
filters = Object.assign({}, defaults, filters);
return data.filter(sheet => {
return (
sheet.fields.slug
.toLowerCase()
.includes(filters.fields.slug) ||
sheet.frontmatter.title
.toLowerCase()
.includes(filters.frontmatter.title)
);
});
}
const result = filterData(nodes, {
fields: { slug: searchTerm },
frontmatter: { title: searchTerm },
headings: { value: searchTerm },
});
The above works, it’s when I try filter on the headings
, so for now let’s take out the filters for slug
and title
and take a look at the last part:
function filterData(data, filters = {}) {
const defaults = {
fields: { slug: null },
frontmatter: { title: null },
headings: { value: null },
};
filters = Object.assign({}, defaults, filters);
return data.filter(sheet => {
return (
sheet.headings.map(h =>
h.value.toLowerCase().includes(filters.headings.value)
)
);
});
}
const result = filterData(nodes, {
fields: { slug: searchTerm },
frontmatter: { title: searchTerm },
headings: { value: searchTerm },
});
If I console.log
, title
and slug
I’ll get true
for each of the three objects.
If I do the same for the for the headings value
I’ll get an array for the headings, like, say if I input fish
I’ll get one element in one of the arrays, like:
[false, false]
[false, true, true, false]
[false, false, false]
What I need to do, but cant work out how to right now is return true for the whole node, I think.
What are you thoughts?
I have made a codesandbox.io example for everyone to take a look at too.