0

I need to recursively navigate through a tree of objects until I find the matching element and push some data into it. Here's a simplified example of my structure:


post.comments = [
    {
        _id: a,
        content: 'Foo',
        replies: [
            {
                _id: aa,
                content: 'Foobar',
                replies: [
                    {
                        _id: aaa,
                        content: 'Foobarbaz',
                        replies: [...]
                    }
                ]
            },
            {
                _id: ab,
                content: 'Barfoo',
                replies: [...]
            }
        ]
    },
    {
        _id: b,
        content: 'Bar',
        replies: [...]
    },
    {
        _id: c,
        content: 'Bar',
        replies: [...]
    },
    ...
]

The replies can be nested infinitely, in theory.

And here's my recursive function:

function findNode(comments, id, data) {
    for (let key in comments) {
        currentNode = comments[key]
        if (currentNode._id.equals(id)) {
            currentNode.replies.push(data)
            break;
        } else {
            if (currentNode.replies.length) {
                findNode(currentNode.replies, id, data)
            }
            else {
                continue;
            }
        }
    }
}

findNode(post.comments, id, comment)

This function appears to only read through the child nodes of the first comment object, then exits with 'Cannot read property 'equals' of undefined' when it reaches a node without children (but I presumed that the continue; should pull it out of that branch of the tree?)

What is it I'm not getting about for loops and recursion?

EDIT: Sorry! string.equals(id) comes from Mongoose - it's equivalent to string == id for the puropses of this example array.

4
  • You need to declare currentNode with let or var or else it's global. Commented Jun 13, 2019 at 14:53
  • why you can not use lodash or _? Commented Jun 13, 2019 at 14:55
  • 2
    Where is String.equals defined? Did you mean if (currentNode._id == id) ? Commented Jun 13, 2019 at 15:07
  • where is the .equals method coming from? A vanilla comparison in JavaScript looks like comments.id === id. Commented Jun 13, 2019 at 15:27

1 Answer 1

4

You can't use currentNode.replies.length if currentNode.replies is undefined. You should check if currentNode.replies is not null, would go somewhat like this:

if (currentNode.replies && currentNode.replies.length) { ...

EDIT: same goes for currentNode._id, check if it is not null before calling currentNode._id.equals.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! That solved the original problem - but now I'm getting RangeError: Maximum call stack size exceeded and I don't understand why! I think I'm covering all the cases??

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.