Finding nested elements Typescript Array object

I have a bunch of content in an array with type:

export interface StaticContent {
  level : number,
  id : string,  
  title: string,
  content : string[] | StaticContent[],
}

I'm trying to search for an object where id to query is a sub-element to a content object. I think I've probably set the interface up wrong but I'm having a mental block.

Any ideas?

Example:

data = [
{
  level: 0,
  id: 'first-element',
  title: 'Title of the first element'
  content: [
    `I am some random string of content`
  ]
},
{
  level: 1,
  id: 'second-element',
  title: 'Title of the second element'
  content: [
     {
       level: 0,
       id: 'first-sub-element',
       title: 'Title of first sub element'
       content: [
         ` I am some content attached to the first sub element `
       ]
     }
}]

let idToFind = 'first-sub-element'
let element = data.find(t => t.id === idToFind)
let title = element.title

In this example the result is an undefined element.
I expect

element = {
       level: 0,
       id: 'first-sub-element',
       title: 'Title of first sub element'
       content: [
         ` I am some content attached to the first sub element `
       ]
     }
}

Solution 1:

You need to use recursion or do a recursive search in place.

Here is recursion example:


function searchInContent(idToFind: string, content: StaticContent[] | string[]): StaticContent | null {   
    for (const c of content) {
       if (typeof c === 'string') continue
 
       // now we can assume that c is StaticContent
       if (c.id === idToFind) {
          // FOUND RESULT
          return c
       } 
   
       // Perform deep search in content
       const result = searchInContent(idToFind, c.content)
       if (result !== null) {
          // stop searching and pass found result
          return result
       }
    }
    return null
}

let idToFind = 'first-sub-element'
let element = searchInContent(data)
let title = element.title

Solution 2:

You are trying to find the content object for a specific id. What you could do is flatMap() the contents and then use find() to find the correct matching object.

const data = [{
    level: 0,
    id: 'first-element',
    title: 'Title of the first element',
    content: [
      `I am some random string of content`
    ]
  },
  {
    level: 1,
    id: 'second-element',
    title: 'Title of the second element',
    content: [{
      level: 0,
      id: 'first-sub-element',
      title: 'Title of first sub element',
      content: [
        ` I am some content attached to the first sub element `
      ]
    }, {
      level: 0,
      id: 'first-sub-elemeeent',
      title: 'Title of first sub element',
      content: [
        ` I am some content attached to the first sub element `
      ]
    }]
  }
];

const idToFind = 'first-sub-element';
const result = data.flatMap(d => d.content).find(c => c.id === idToFind);

console.log(result);