简体   繁体   中英

Creating tree recursively using JavaScript

I want to create a tree using a recursive function. The input to this function is a node and I want to add its children to it with that recursive function.

The following code will explain my problem in a better way:

 function getUpstreamChildrenRecusrively(node) { var receiverId = localStorage.getItem("ReceiverId"); //API call to get the children node axios({ method: 'get', url: window.location.origin+"/api/rwa/coverageView/getUpstreamChildren?id="+node.elementId, headers: { "ReceiverId":receiverId } }) .then(response => { localStorage.setItem("ReceiverId",response.headers["receiverid"]); var data = response.data; for(var i = 0; i < data.length; i++) { var obj = data[i]; var result = {}; result.text = obj.print; result.elementId = obj.id; result.elementText = obj.text; result.expanded = true; result.visible = true; result.icon = window.location.origin+"/api"+obj.image; getUpstreamChildrenRecusrively(result); node.nodes = []; //nodes property will contain children node.nodes.push(result); console.log("Tree so far:"+JSON.stringify(node)); } }) .catch(error => { }) } 

For every recursive call, the value of the node is a separate node having a single child in nodes property. I want to see the node to be grown with all its children as a final result.

What am I missing in this code?

Thank you in advance!

Your understanding of how recursion works is flawed, I am not trying to be rude, just trying to help you understand that you need to study the subject more.

  1. First of all you are not returning anything from your function
  2. You are also checking the value of node after you have called your function recursively (which performs an async call and is scoped to the current function call).
  3. You are making recursive api calls with no check in place for when the function should stop executing. Which means it will run until your api call fails.

  function getUpstreamChildrenRecusrively(node) { var receiverId = localStorage.getItem("ReceiverId"); //Api call to get the children node return axios({ method: "get", url: window.location.origin + "/api/rwa/coverageView/getUpstreamChildren?id=" + node.elementId, headers: { ReceiverId: receiverId } }) .then(response => { localStorage.setItem("ReceiverId", response.headers["receiverid"]); var data = response.data; for (var i = 0; i < data.length; i++) { var obj = data[i]; var result = {}; result.text = obj.print; result.elementId = obj.id; result.elementText = obj.text; result.expanded = true; result.visible = true; result.icon = window.location.origin + "/api" + obj.image; node.nodes = getUpstreamChildrenRecusrively(result); //nodes property will contain children console.log("Tree so far:" + JSON.stringify(node)); return node; } }) .catch(error => { /* I am using ES6 here, you can use something equavelant to check if node has a value */ if (Object.keys(node).length > 0) { return node; } else { /* obviously you need other error handling logic here too */ } }); } 

It looks like you expect your getUpstreamChildrenRecusrively to work synchronously. Learn more about javascript async/await and Promises.

here is how it should probably work

async function getUpstreamChildrenRecusrively(node) {
  const receiverId = localStorage.getItem("ReceiverId")

  const response = await axios({
    method: 'get',
    url: window.location.origin+"/api/rwa/coverageView/getUpstreamChildren?id="+node.elementId,
    headers: {
      ReceiverId: receiverId
    }
  })

  localStorage.setItem("ReceiverId",response.headers["receiverid"])
  const data = response.data

  node.nodes = node.nodes || []

  for(let i = 0; i < data.length; i++) {
    const obj = data[i]
    const result = {}
    result.text = obj.print
    result.elementId =  obj.id
    result.elementText = obj.text
    result.expanded = true
    result.visible = true 
    result.icon = window.location.origin + "/api" + obj.image
    node.nodes.push(result)
    await getUpstreamChildrenRecusrively(result)               
  }                                     
}

getUpstreamChildrenRecusrively(initialNode).then(() => {
  console.log('result node', initialNode)
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM