Basti
Basti

Reputation: 517

Javascript Treeview, Array inside Array

I am working on a treeview and I created a class Node, consisting of a name and a list of children.

class Node {
  constructor(name, childNodes) {
    this.name = name;
    this.childNodes = childNodes;
  }
}

I am trying to create an object looking like the object "tree" in the image below. Every Node has a attribute called "nodes" which is the childNode-Array. I got very close to creating the same tree, but in my version there is an extra "Array"-Layer around each of the Child nodes (see the recTreeview()-Element):

enter image description here

I am not sure how to fix this problem. The array has to be created to contain the childnodes. Here is the code where the treeview Element is created:

function recTreeview(currentNode, treeview) {
  var tempChildren = [];
  currentNode.children.forEach(child => {
    tempChildren.push(recTreeview(child, []));
  });
  treeview.push({
    text: currentNode.name,
    nodes: tempChildren
  });

  return treeview;
}

Is there anything I can do? Update: A Code-Snippet:

class Node {
  constructor(name, children) {
    this.children = children;
    this.name = name;
  }
}

function recTreeview(currentNode, treeview) {
  var tempChildren = [];
  currentNode.children.forEach(child => {
    tempChildren.push(recTreeview(child, []));
  });
  treeview.push({
    text: currentNode.name,
    nodes: tempChildren
  });

  return treeview;
}

child1 = new Node("child1", []);
child2 = new Node("child2", []);
parent = new Node("Parent", [child1, child2]);

var tree = [
  {
      text: "Parent 1",
      nodes: [
          {
              text: "Child 1"
          },
          {
              text: "Child 2"
          }
      ]
  }
];
<button onClick="console.log(recTreeview(parent, []));">Wrong</button>
<button onClick="console.log(tree);">Right</button>

Upvotes: 1

Views: 1314

Answers (1)

ibrahim mahrir
ibrahim mahrir

Reputation: 31712

The extra array is comming from tempChildren.push(recTreeview(child, []));. Because you are pushing the return value of recTreeview (which is an array) to the children array tempChildren.

Instead of pushing the new array to tempChildren, you should pass tempChildren as the parameter to recTreeview:

currentNode.children.forEach(child => {
    recTreeview(child, tempChildren);
});

So that the children will be pushed directly to the tempChildren array instead of getting wrapped in the extra array recTreeview is creating.

Example:

class Node {
  constructor(name, children) {
    this.children = children;
    this.name = name;
  }
}

function recTreeview(currentNode, treeview) {
  var tempChildren = [];
  currentNode.children.forEach(child => {
    recTreeview(child, tempChildren);
  });
  treeview.push({
    text: currentNode.name,
    nodes: tempChildren
  });

  return treeview;
}

child1 = new Node("child1", []);
child2 = new Node("child2", []);
parent = new Node("Parent", [child1, child2]);

var tree = [
  {
      text: "Parent 1",
      nodes: [
          {
              text: "Child 1"
          },
          {
              text: "Child 2"
          }
      ]
  }
];
<button onClick="console.log(recTreeview(parent, []));">Not Wrong Anymore</button>
<button onClick="console.log(tree);">Right</button>

Note:

If you want to get rid of that empty nodes array if there are no children, then change this:

treeview.push({
    text: currentNode.name,
    nodes: tempChildren
});

To:

var node = {
    text: currentNode.name
};
if(tempChildren.length) {
    node.nodes = tempChildren;
}
treeview.push(node);

Which only adds the nodes property if the tempChildren array is not empty.

Upvotes: 2

Related Questions