Search code examples
javascriptreactjstreeviewjavascript-objectshierarchy

How show javascript object as html tree?


I would like to generate a tree from the following object:

configuration:

  {
    name: "General",
    icon: "general",
    children: [
      {
        name: "Line 1",
        icon: "line",
        children: [
          {
            name: "Area 1",
            icon: "area",
            children: [
              { name: "Y", icon: "x" },
              { name: "Z", icon: "z" },
            ],
          },
          { name: "Area 2", icon: "line" },
        ],
      },
      {
        name: "Line 2,
        icon: "line",
        children: [{ name: "Area 3", icon: "area" }],
      },
    ],
  },

In html I have my own custom element:

<my-details>
            <div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
            ${this.children} // ???
</my-details>`;

so I created the function:

 createHierarchy() {
    if (configuration?.length > 0) {
      const details = _configuration.map(({ name, icon }) => {
        return ` <my-details>
            <div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
            ${this.children}
           </my-details>`;
      });

      hierarchyContainer.innerHTML = details?.join("");
    }
  }

but I don't know how to convert this structure in a loop or map to a tree, each element of the hierarchy should be a my-details element and have a name as a slot and in the middle it should have children

the structure should look like this: hierarchy tree


Solution

  • What you are looking for is a recursive function. Which is a function that calls itself.

    It should end up looking something like this:

    function parseNode(node) {
      let html = `<my-details>
        <div slot="summary">
           <my-icon name="${node.icon}"></my-icon>
           ${node.name}. 
        </div>`;
      if(node.children) {
        node.children.forEach(childNode => {
          html += parseNode(childNode);
        })
      ;}
      html += '</my-details>';
      return html;
    }
    
    parseNode(configuration);
    

    This example turns your entire configuration into an html string (or it should it is untested). You can output to your document/component.

    Note that it relies on all nodes having a name and an icon and a possible "children" has to be an array.