SamTV
SamTV

Reputation: 147

Traverse and Replace Items in TreeData

I am stuck at the task of traversing a tree and replacing the nodes if they match the key. This is necessary as I load children lazy via REST, insert them into the parent node and then replace the parent node (The node I clicked onto) with the parent with loaded children.

The treeData interface is:

export interface TreeData {
    keyNum:number,
    icon:string,
    name:string,
    length:number,
    type: string,
    links: string,
    children?: TreeData[]
}
_nodes = Temp array that replaces the current nodes
nodes = All elements 
event = Current parent
test = Temporary array for pushing items when doing it recursively

In a first attempt I created this function:

let _nodes = nodes.map(node => {
      if (node.keyNum=== event.keyNum) {
          node = event;
      }

     return node;
})
setNodes(_nodes)

Unfortunately this doesn't do this recursively. Only when I open up the root item. In a next attempt I created this function:

const test = [] as TreeData[]
traverseTree(event,nodes, test)
dispatch(setNodes(test))


const traverseTree = (event: TreeData, currentNodes: TreeData[], temp: TreeData[])=>{
          currentNodes.forEach(node=>{
            if (node.keyNum === event.keyNum) {
                node = event;
                temp.push(node)
            }
            else{
                if(node.children && node.children.length>0){
                    return node.children.forEach(nodeInLoop=>{
                        return traverseTree(event,[nodeInLoop], temp)
                    })
                }
            }
        })
    }

I can finally traverse the tree but the problem is that when I click element1

-root
   - element 1
   - element 2

this gets transformed to:

- element 1
   - subelement 1
   - subelement 2
   - ...

So when I click a child everything above is replaced. How can I preserve also the parent when clicking element 1. So that the expected output is

- root
   - element 1
      - subelement 1
      - subelement 2
      - ...
   - element 2

Upvotes: 0

Views: 61

Answers (1)

trincot
trincot

Reputation: 350290

I would not use a third parameter like in your recursive code. Instead make the function return the new tree.

It is indeed a problem that in your attempt the only thing that happens to temp is that nodes are pushed unto it. But you'll also need to repopulate children arrays in the hierarchy. You can better use map for that, and spread syntax to clone nodes with newly created children arrays.

Your recursive attempt could be corrected like this:

const traverseTree = (event: TreeData, nodes: TreeData[]): TreeData[] =>
    nodes.map(node =>
        node.keyNum === event.keyNum ? event
            : !node.children?.length ? node
            : { ...node, children: traverseTree(event, node.children) };
    );

Call like:

dispatch(setNodes(traverseTree(event,nodes)))

Upvotes: 1

Related Questions