0

Thanks for helping in advance. Can you please help me find the mistake I am making in this code:

<script>
  function getChildrenRecursively(parent) {
    returnValue = [];
    var children = getChildren(parent);
    children.forEach(function(child, index, array) {
      itemData = new Object();
      itemData.id = parent + "_" + index + "_" + child;
      itemData.items = getChildrenRecursively(child);

      returnValue.push(itemData);
    })
    return returnValue;
  }

  function getChildren(parentId) {
    if (parentId == 1) return [2, 3];
    if (parentId == 2) return [4];
    if (parentId == 3) return [5, 6];
    if (parentId == 4) return [];
    if (parentId == 5) return [];
    if (parentId == 6) return [];
  }

  console.log(getChildrenRecursively(1));
</script>

getChildrenRecursively(parentId) is a recursive method that gathers children of passed parent id (by calling getChildren(parentId)) and then it calls itself recursively for each childid to gather children of children and so on. The output I expect from returnValue is this:

An array with 2 elements since parentId "1" has 2 children "2" and "3". Then "2" will have a subarray of 1 element "4" and "3" will have a subarray of 2 elements "5" and "6". But I get this and each subchild has 2 children and so on endlessely, please help me figure out the bug in code:

incorrect output

2
  • When you are setting something in a function that you are trying to use later, I'd use let itemData = new Object();. After all of the executions itemData likely will be set to whatever the last assignment was that was executed. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… has information about let. Commented Sep 27, 2017 at 14:37
  • returnValue = []; <--- global Commented Sep 27, 2017 at 14:45

2 Answers 2

1

See the changes below. I have added let and changed var to let. It appears that you have run into an issue known as Temporal Dead Zone (as described by Mozilla)

More information about it can be found here. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

<script>
  function getChildrenRecursively(parent) {
    let returnValue = [];
    let children = getChildren(parent);
    children.forEach(function(child, index, array) {
      let itemData = new Object();
      itemData.id = parent + "_" + index + "_" + child;
      itemData.items = getChildrenRecursively(child);

      returnValue.push(itemData);
    })
    return returnValue;
  }

  function getChildren(parentId) {
    if (parentId == 1) return [2, 3];
    if (parentId == 2) return [4];
    if (parentId == 3) return [5, 6];
    if (parentId == 4) return [];
    if (parentId == 5) return [];
    if (parentId == 6) return [];
  }

  console.log(getChildrenRecursively(1));
</script>

Sign up to request clarification or add additional context in comments.

Comments

0
function getChildrenRecursively(parent) {
  const children = getChildren(parent);
  const arrReturn = children.map(
      (child, index) => ({
          id: parent + "_" + index + "_" + child,
          items: getChildrenRecursively(child),
      }));
  return arrReturn;     
}

function getChildren(parentId) {
  switch (parentId) {
     case 1: return [2, 3];
     case 2: return [4];
     case 3: return [5, 6];
     default: return [];
  }
}

IMO there are still some issues with this. getChrildrenRecursively doesn't really get children, but builds a tree. With one adjustment it would include the root:

function getTree(parent) {
  function createNode(id, index = 0) {
      return {
          id: parent + "_" + index + "_" + id,
          items: getChildren(id).map(createNode);
      };
  }
  return createNode(parent);
}
console.log(getTree(1).items);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.