Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

191
Vistas
Javascript: Recursion returning undefined

Why is my recursion returning undefined? I'm trying to "decode" nested children data from mongo which is returned as IDs like:

{
    "_id": "613fd030f374cb62f8f91557",
    "children": [
        "613fd035f374cb62f8f9155b",
        "613fd136f374cb62f8f91564",
        "613fd1a5f374cb62f8f91571",
        "613fd20bf374cb62f8f9157c"
    ],
    ...more data
}

My goal is to drill down and convert each child ID to the Object the ID represensents and convert their child IDs to objects then keep going until the child === [] (no children). I'm trying to have the initial parent (613fd030f374cb62f8f91557) have access to all multi-level nested children objects.

This is my code:

const get_documents = (documents) => {
    // Loop through each document

    documents.map((document) => {
      if (document.parent === null) {
        //convert children ids (_id) to array of objects
        let dbData = [];

        document.children.map((id) => {
          let dbChildren = documents.find((x) => x._id === id);
          dbData.push(dbChildren);
        });

        let formattedData = [];

        dbData.map((child) => {
          let formattedObject = {
            id: child._id,
            name: child.name,
            depth: 0,
            parent: child.parent,
            closed: true,
            children: child_recursion(child.children), 
          };
            formattedData.push(formattedObject)
        });
      }
    });
  };
const child_recursion = (arr) => {
    let dbData = [];

    arr.map((id) => {
      let dbChildren = documents.find((x) => x._id === id);
      dbData.push(dbChildren);
    });

    let formattedData = [];

    dbData.map((child) => {
      
      let newChild = [];

      if (child.children.length > 1) {
        newChild = child_recursion(child.children);
      }

      let formattedObject = {
        id: child._id,
        name: child.name,
        depth: 0,
        parent: child.parent,
        closed: true,
        children: newChild,
      };
      
      formattedData.push(formattedObject);
     
     if (newChild === []) {
      return formattedData
     }
    });
  };

What am I doing wrong in my recursion? Thank you for the help!

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

What is getting you here is mixing mutation with recursion which tends to make things a lot more messy.

What this line is telling me:

children: child_recursion(child.children), 

is that you are always expecting child_recursion to return an array of formatted children.

However, in child_recursion you aren't always returning something. Sometimes you are mutating sometimes instead. Personally, I believe that it tends to be easier to wrap my head around not using mutation.

The process, therefore, should go something like this:

  1. given an object
  2. check if that object has children
    1. if it does convert the children using this function
    2. if it does not, stop recursion
  3. return a new object, created from the input object with my children set to the output of the conversion.

In this way we can convert each child into an object with its children converted and so on.

Also it is somewhat strange that you are trying to convert all documents at once. Instead, as you gave in your question, you should focus on the object you are trying to convert and work downwards from there. If it is the case where objects can be both parents and children then you have a graph, not a tree and recursion would have to be handled differently than you are expecting.

We don't really need two functions to do this, just one and in the case where you already have the objects you are searching you can pass that along as well (if you don't just remove documents and get them from the db or some service instead). We can also use what is called an accumulator to set initial values before our recursion and track them as we recur.

const convert_children = (obj, documents) => {
  const convert_children_acc = (obj, documents, parent, depth) => {
    let partial_format = {
      id: obj._id,
      name: obj.name,
      depth: depth,
      parent: parent,
      close: true
    }
    if (obj.children && obj.children.length === 0) {
      return {
        ...partial_format,
        children: []
      }
    } else {
      return {
        ...partial_format,
        children: obj.children.map(child => {
          child = documents.find(x => child === x._id);
          return convert_children_acc(child, documents, obj._id, depth+1)
        })
      }
    }
  }
  return convert_children_acc(obj, documents, null, 0);
};

https://jsfiddle.net/5gaLw1y7/

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda