0

var treeDataOld = [
			{id: '1', pId: '', name: 'root1', checked: false},
			{id: '2', pId: '', name: 'root2', checked: false},
			{id: '3', pId: '', name: 'root3', checked: true},
			{id: '4', pId: '1', name: 'child', checked: true},
			{id: '5', pId: '4', name: 'child', checked: false},
			{id: '6', pId: '5', name: 'child', checked: false},
			{id: '7', pId: '6', name: 'child', checked: false},
			{id: '8', pId: '7', name: 'child', checked: true},
			{id: '9', pId: '8', name: 'child', checked: false},
		];

function findRoot(node) {
    var getParentNode = function (node, refArray) {
        var len = refArray.length;
        for (var i = 0; i < len; i++) {
            if (refArray[i].id === node) {
                return refArray[i];
            }
        }
    };

    if (node.pId !== '') {
        findRoot(getParentNode(node.pId, treeDataOld));
    } else { 
        console.log(node);   // I got OBJECT here
        return node;
    }
}

var rootNode = findRoot(treeDataOld[8]);
console.log(rootNode);   // here is UNDEFINED

I want to find the root node by giving a parent node. I got correct result at first console inside function findRoot before return. But the console outside the function get UNDEFINED.

3 Answers 3

2

The findRoot() function does not return anything after making the first recursive call. What you want is the following:

if (node.pId !== '') {
    return findRoot(getParentNode(node.pId, treeDataOld));
}
Sign up to request clarification or add additional context in comments.

Comments

0

You are using recursive call, but you don't return anything, maybe this is the cause, try to put return before the findRoot(getParentNode(node.pId, treeDataOld)); and than you have this return findRoot(getParentNode(node.pId, treeDataOld));

var treeDataOld = [
			{id: '1', pId: '', name: 'root1', checked: false},
			{id: '2', pId: '', name: 'root2', checked: false},
			{id: '3', pId: '', name: 'root3', checked: true},
			{id: '4', pId: '1', name: 'child', checked: true},
			{id: '5', pId: '4', name: 'child', checked: false},
			{id: '6', pId: '5', name: 'child', checked: false},
			{id: '7', pId: '6', name: 'child', checked: false},
			{id: '8', pId: '7', name: 'child', checked: true},
			{id: '9', pId: '8', name: 'child', checked: false},
		];

		function findRoot(node) {
			var getParentNode = function (node, refArray) {
				var len = refArray.length;
				for (var i = 0; i < len; i++) {
					if (refArray[i].id === node) {
						return refArray[i];
					}
				}
			};

			if (node.pId !== '') {
				return findRoot(getParentNode(node.pId, treeDataOld));
			} else {
				console.log(node);   // I got OBJECT here
				return node;
			}
		}

		var rootNode = findRoot(treeDataOld[8]);
		console.log(rootNode);   // here is UNDEFINED

Comments

0

Your basic problem can be solved by returning the value from findRoot as other answers have suggested. However, your code can be made more legible (and less susceptible to bugs such as the one you ran into) by simplifying it as:

function findRoot(node) {
  var findParentNode = (id, refArray) => refArray.find(node => node.id === id);
  var pId = node.pId;

  return !pId ? node : findRoot(findParentNode(pId, treeDataOld));
}

Now, the classic recursion pattern--check for base case, then recursive case--is clearly visible.

We're using Array#find here to factor out the basic lookup logic so it does not clutter up your algorithm. If you don't have Array#find available, use a polyfill or write your own.

We're also using arrow functions--if you don't have those available, rewrite using standard function notation.

If you want to refactor further, you could write a lower-level findByProp to find a particular array element based on the value of one of its properties:

function findByProp(array, prop, value) {
  return array.find(elt => elt[prop] === value);
}

Now you can write this as

function findRoot(node) {
  var findParentNode = (value, array) => findByProp(array, 'id', value);
  var pId = node.pId;

  return !pId ? node: findRoot(findParentNode(pId, treeDataOld));
}

Or if you prefer one-liners

function findRoot(node) {
  return !node.pId ? node : findRoot(findByProp(treeDataOld, 'id', node.pId));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.