Traverse – very useful npm package

NPM has a lot, a lot of useful packages… and a lot of useless packages of course. Sometimes we can find something very nice. Last time I must modified nested object in JavaScript. I can write my own function to do this, use recursion for example, but I simply… didn’t have enough time to do this. I must find solution quickly, good solution. I and found – it’s traverse package. Yes, its name is very meaningful.

This note is about this package, but it isn’t full description and review – I had to use only limited options of traverse, and just can’t say a lot about other of its features. If you can say something about that, feel free and add comment – I will be very grateful. Traverse is available on npm and also on Github. It isn’t actively developed, last changes are from 5-6 years ago… I know, it sounds bad, but this package just works and does, what it should do. As you can guess, we can use it to travel through JavaScript objects.

First of thing – traverse will travel whole object, so it’s a recursive walk – very, very nice feature, because sometimes we don’t know, how “deep” is our object. I use complex and nested structure: nesting level is is dependent on the user’s actions so… I can’t predict anything. I only know, that there will be nested object…. and must check few thing in this object, in each level. With traverse, it’s very easy. There is small example how we can use this package:

let myNestedObject = {}
myNestedObject = getNestedObject()

// Walk through object, we use lodash here
traverse(myNestedObject).forEach(function (x) {

    // No next object? 
    if (!_.isObject(x)) {
        console.log('Leaf')
    }

    // Check if property exists
    if (_.isObject(x) && !_.isUndefined(x.myProp)) {
      console.log(x.myProp)
    }

    // Display object parent info
    console.log(this.parent)

    // Get proparty for parent node
    console.log(this.parent.node_)

    // Get deep level
    console.log(this.level)

    // Same some changes?
    x.newProp = 123
    x.myProp = 'Changed!'

    // This new object will be also "scanned!"
    x.nestObject = {
    	test: 1
    	foo: 'bar'
    }

    // Save changes
    this.update(x)
})

As you can see, we have available each nested object and each leaf as forEach argument – sometimes it will be object, sometimes something else. We can not only display properties, but also modify them. It’s very important to say, that if we for example add new nested object, it will be also checked! It’s default behavior, but we can change this using false argument. Modifying is not the only option, because we can also delete objects, clone them and run callbacks before/after walking in each leaf. Some this properties allows us to check that current leaf is root, has children, check deep level etc. – all options is available on npm Traverse website.

One important question is: how can I stop traversing? In many cases, we want “scan” object, find something and then stop, not continue. It’s very important because of performance: use such recursion is hard work and we should stop it as soon as possible. Fortunatelly, it’s possible and you can achieve it in this way:

let BreakException = {}
let workDone = false

try {
traverse(myNestedObject).forEach(function (x) {

	// Here get required data or modify object... 
	// Check our condition, stop traversing
	if (workDone) {
	    throw BreakException
	}
})
} catch (e) {
}