I am trying to traverse through my array to get a specific object nested inside of it.
Some objects contain a children
property, which should be traversed until a matching object is found.
Here's some example data, I am trying to obtain the object with id
as 4
const items = [{
id: 1,
title: 'Title for Item 1'
},
{
id: 2,
title: 'Title for Item 2',
children: [
{
id: 3,
title: "Title for Item 3",
children: [
{
id: 4,
title: "Title for Item 4",
}
]
}
]
},
]
I've written some traversal code but it returns undefined
.
const items = [{
id: 1,
title: 'Title for Item 1'
},
{
id: 2,
title: 'Title for Item 2',
children: [
{
id: 3,
title: "Title for Item 3",
children: [
{
id: 4,
title: "Title for Item 4",
}
]
}
]
},
]
const getItem = (items) => {
if (!items) return;
const item = items && items.find(i => i.id === 4);
if (!item) {
items.forEach(i => {
return getItem(i.children)
})
// This is where undefined is returned
} else {
console.log({
item
}) // Prints the correct object.
return item;
}
};
const s = getItem(items); // undefined
document.querySelector('#foo').textContent = s ? s : 'undefined';
<div id="foo"></div>
At least two issues explain why it does not work:
return
statement in a forEach
callback will return the returned value to nowhere. Nothing happens with it.Replace that forEach
with a for...of
loop so you can return "out of it", but only do that when you have a match, otherwise you need to continue the loop:
for (const item of items) {
const match = getItem(item.children);
if (match) return match;
}
Note that in your snippet you should not set the textContent
to the return value, as that is an object and will get converted to the string "[Object object]". You could for instance just grab the title string and put that in textContent
:
const items = [{
id: 1,
title: 'Title for Item 1'
},
{
id: 2,
title: 'Title for Item 2',
children: [
{
id: 3,
title: "Title for Item 3",
children: [
{
id: 4,
title: "Title for Item 4",
}
]
}
]
},
]
const getItem = (items) => {
if (!items) return;
const item = items && items.find(i => i.id === 4);
if (!item) {
for (const item of items) {
const match = getItem(item.children);
if (match) return match;
}
} else {
console.log({
item
}) // Prints the correct object.
return item;
}
};
const s = getItem(items); // undefined
document.querySelector('#foo').textContent = s ? s.title : 'undefined';
<div id="foo"></div>