Recursively iterate through multi nested arrays in the lwc’s html file

childrelationshiphtmllightning-web-componentsloop

I have the following data and nested a way to recursively call the same logic so that regardless of how many levels are in the data, the data is always printed correctly in a nested format.

Example Data 1

Parent
        child1
        child2
                grandchild4

        child3
                grandchild
                grandchild
                        greatgrandchild
                        greatgrandchild
                grandchild
                        greatgrandchild
                        greatgrandchild
                                greatgreatgrandchild
                        greatgrandchild

Example Data 2

Parent
        child1
        child2
                grandchild4

        child3
                grandchild
                grandchild
                grandchild
                     

Questions

  1. How can I dynamically iterate through the child arrays regardless of how deep the nested arrays are?
  2. Can I call the same component within itself or do I have to call a child component that will recursively call itself if it finds there are more child arrays? If so, how could I do that?

What I tried but it requires me to know the level, which I won't know for every record

<template for:each={myAry} for:item="item">
  <ul key={item.id}>
    <li> {item.name} </li>
    <template lwc:if={item.children}>
      <ul>
         <template for:each={item.children} for:item={child}> 
           <li key={child.Id}> {child.Name}</li>
           <template lwc:if={child.children}> 
              <ul>
                 <template for:each={child.children} for:item={grandchild}> 
                   <li key={grandchild.Id}> {grandchild.Name}</li>
                 
                   <!-- there could be more child arrays but I need to be able to dynamically call this logic if there are nested children -->
                 </template>
              </ul>
           </template>
         </template>
      </ul>
    </template>
  </ul>
</template>

Best Answer

A component can reference itself recursively. I previously wrote this in Aura, but the principle remains the same.

First, we just translate the markup to a LWC template:


<div>
    <div onclick={toggle}>
        <template lwc:if={node.items.length}>
            [ <template lwc:if={!expanded}>-</template>
              <template lwc:else>+</template> ]
        </template> {node.Name}
    </div>
    <template lwc:if={expanded}>
        <div class="node">
            <template for:each={node.items} for:item="node">
                <c-tree-node key={node.Id} node={node}></c-tree-node>
            </template>
        </div>
    </template>
</div>

The corresponding CSS for this doesn't change much:

.node {
    margin-left: 1em;
}

Nor does the controller logic:

toggle() {
  this.expanded = !this.expanded;
}

You can see the full code on the linked answer if you need additional help from there.

Because of the requirement to have a key, you'll want to generate keys or use record Id values, whichever is acceptable for your use case.

Demo.

Related Topic