0

I'm still new to recursive functions but I'm having trouble returning the object once found to a variable (currently searching based on ID). I've included a dataset below and what I have so far. The recursive function finds the correct matching item, but when it returns it, it just returns undefined to the variable. I have tried the solution here and also get the same problem I have where it just returns undefined instead of the object. Any help/pointers would be great!

const data = {
    "navItems": [
        {
            "type": "directory",
            "id" : 1,
            "name": "Nav Title 1",
            "children": [
                {
                    "downloadUrl": "",
                    "content": "",
                    "id" : 2,
                    "type": "file",
                    "name": "File 1.pdf"
                },
                {
                    "downloadUrl": "",
                    "content": "",
                    "type": "file",
                    "id" : 3,
                    "name": "File 2.pdf"
                },
                {
                    "type": "directory",
                    "name": "Sub Title 1",
                    "id" : 4,
                    "children": [
                        {
                            "downloadUrl": "",
                            "content": "",
                            "type": "file",
                            "id" : 5,
                            "name": "Sub File 1.pdf"
                        },
                        {
                            "downloadUrl": "",
                            "content": "",
                            "type": "file",
                            "id" : 6,
                            "name": "Sub File 2.docx"
                        }
                    ]
                },
                {
                    "type": "directory",
                    "name": "Sub Title 2",
                    "id" : 7,
                    "children": [
                        {
                            "type": "directory",
                            "id" : 8,
                            "name": "Sub Sub Title 1",
                            "children": [
                                {
                                    "downloadUrl": "",
                                    "id" : 9,
                                    "content": "",
                                    "type": "file",
                                    "name": "Sub Sub File 1.pdf"
                                },
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "type": "file",
                                    "id" : 10,
                                    "name": "Sub Sub File 2.pdf"
                                }
                            ]
                        },
                        {
                            "type": "directory",
                            "name": "Sub Sub Title 2",
                            "id" : 11,
                            "children": [
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "id" : 12,
                                    "type": "file",
                                    "name": "Sub Sub File 1.pdf"
                                },
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "id" : 13,
                                    "type": "file",
                                    "name": "Sub Sub File 2.pdf"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

/* console.log(navigationConfig);*/

const searchNavItems = (navItem) => {

  if (navItem.id == 10) {
    console.log(navItem);
    return navItem;
  } else {
    if (navItem.hasOwnProperty("children") && navItem.children.length > 0 && navItem.type == "directory") {
      navItem.children.map(child => searchNavItems(child))
    } else {
      return false;
    }
  }
};


 let dataItem = data.navItems.forEach((item => {
       let nav = searchNavItems(item);
        console.log(nav);
  }))

  console.log(dataItem)
Ancesteral
  • 109
  • 9
  • `forEach` doesn’t return a value (even if you were returning something in the callback) – Dave Meehan Jul 08 '22 at 06:19
  • Instead `navItem.children.map(child => searchNavItems(child))` (which does not return anything), please try: `return navItem.children.map(child => searchNavItems(child)).flat().filter(Boolean)`. Instead of making a recursive call for "each" element of an array, we may make the recursion happen at the array-level (as demonstrated in the answer I've provided), if that is okay to do. – jsN00b Jul 08 '22 at 06:54

2 Answers2

0

in your fn there are couple of problems

  1. when you are maping over children you are not returning the array of children

  2. forEach does not return anything () => void, so you will need to create a new variable to hold that value

let dataItem;

data.navItems.forEach((item) => {
  console.log(searchNavItems(item));
  dataItem = searchNavItems(item);
});

hope this helps

aleEspinosaM
  • 426
  • 2
  • 6
0

Presented below is one possible way to achieve the desired objective.

Code Snippet

const mySearch = (needle, hayStack) => (
  hayStack.some(({ id }) => id === needle)
  ? (
    {children, ...rest} = hayStack.find(({ id }) => id === needle),
    [{...rest}]
  )
  : hayStack.flatMap(
    ({ children = [] }) => mySearch(needle, children)
  )
);

/* explanation of the above method
// method to search for element/s with given "id"
// finding "needle" (ie "id") in hayStack (ie, "array" of objects)
const mySearch = (needle, hayStack) => (
  // check if needle exists in current array
  hayStack.some(({ id }) => id === needle)
  ? (   // find the matching array elt, destructure to access 
        // "children" and "rest" props.
        // send the props other than "children"
    {children, ...rest} = hayStack.find(({ id }) => id === needle),
    [{...rest}]
  )     // if needle is not present in current array
        // try searching in the inner/nested "children" array
  : hayStack.flatMap(     // use ".flatMap()" to avoid nested return
        // recursive call to "mySearch" with "children" as the hayStack
    ({ children = [] }) => mySearch(needle, children)
  )
);
*/

const data = {
  "navItems": [{
    "type": "directory",
    "id": 1,
    "name": "Nav Title 1",
    "children": [{
        "downloadUrl": "",
        "content": "",
        "id": 2,
        "type": "file",
        "name": "File 1.pdf"
      },
      {
        "downloadUrl": "",
        "content": "",
        "type": "file",
        "id": 3,
        "name": "File 2.pdf"
      },
      {
        "type": "directory",
        "name": "Sub Title 1",
        "id": 4,
        "children": [{
            "downloadUrl": "",
            "content": "",
            "type": "file",
            "id": 5,
            "name": "Sub File 1.pdf"
          },
          {
            "downloadUrl": "",
            "content": "",
            "type": "file",
            "id": 6,
            "name": "Sub File 2.docx"
          }
        ]
      },
      {
        "type": "directory",
        "name": "Sub Title 2",
        "id": 7,
        "children": [{
            "type": "directory",
            "id": 8,
            "name": "Sub Sub Title 1",
            "children": [{
                "downloadUrl": "",
                "id": 9,
                "content": "",
                "type": "file",
                "name": "Sub Sub File 1.pdf"
              },
              {
                "downloadUrl": "",
                "content": "",
                "type": "file",
                "id": 10,
                "name": "Sub Sub File 2.pdf"
              }
            ]
          },
          {
            "type": "directory",
            "name": "Sub Sub Title 2",
            "id": 11,
            "children": [{
                "downloadUrl": "",
                "content": "",
                "id": 12,
                "type": "file",
                "name": "Sub Sub File 1.pdf"
              },
              {
                "downloadUrl": "",
                "content": "",
                "id": 13,
                "type": "file",
                "name": "Sub Sub File 2.pdf"
              }
            ]
          }
        ]
      }
    ]
  }]
};

console.log(
  'data for id: 10\n',
  mySearch(10, data.navItems)?.[0]
);
console.log(
  'data for id: 13\n',
  mySearch(13, data.navItems)?.[0]
);
console.log(
  'data for id: 9\n',
  mySearch(9, data.navItems)?.[0]
);
console.log(
  'data for id: 3\n',
  mySearch(3, data.navItems)?.[0]
);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments added to the snippet above.

jsN00b
  • 3,584
  • 2
  • 8
  • 21