NeverNull provides the ability to safely navigate an object tree, regardless if the object, its properties, or nested properties exist.
The browser version of nevernull can be found here
To easily try out nevernull, you can fork the codio project & box here
The function-object returned from nn guarantees safe navigation of its object tree. This allows us to avoid boilerplate value checking.
const emptyObject = {};
const nnEmptyObject = nn(emptyObject);
//this will not throw any errors.
nnEmptyObject.property.that.doesnt.exist;
All properties accessed on a never null function-object are functions. Executing the function property gives you the underlying value of proxied object, should the value exist.
let person = {
name: {
first: 'jason'
}
};
let nnPerson = nn(person);
nnPerson.name(); // == { first: 'jason'}
nnPerson.name.first(); // == 'jason'
nnPerson.name.last(); // == undefined
nnPerson.employer.name(); // == undefined
nn(person).address.city() // == undefined
Property values can be set in several ways.
To assign a property named 'first' to the 'name' target, we can simply access and assign to the raw 'name' object.
nnPerson.name().first = 'jason';
But what if name is undefined? We'd end up with an error.
To avoid the above error, nevernull allows us to avoid boiler plate checking and assign value to the target only if the target is not undefined.
nnPerson.name.first = 'jason';
//since the address object is undefined, setting properties on it will have no effect, and no error will be thrown.
nnPerson.address.city = 'salt lake city';
nnPerson.name.first(); // == 'jason'
nnPerson.address.city(); // == undefined
See the test spec for more examples
npm install nevernull
const nn = require('nevernull');
Nevernull provides you with the same functionality the Existential Operator provides in various other languages (Ruby, Groovy, Dart, CoffeeScript, etc)
e.g.
person?.name?.first; //safe navigation operator in groovy
nn(person).name.first(); //nevernull usage in js
Wikipedia - Save Navigation Operator
Groovy's Safe Navigation Operator
CoffeeScript's Existential Operator
Ruby's Safe Navigation Operator
The proposal for the Existential Operator is currently in Stage 0 draft status.
Stage 0 Draft - Optional Chaining - Spec Text
Stage 0 Draft - Optional Chaining - Github
Optional Chaining aka Existential Operator Null Propagation
Existential Operator Null Propogation Operator
Node 7 provides native Proxy, but 6.x will use a polyfill to emulate Proxy.
Performance is acceptable for most situations, but it should be noted that there can be a performance penalty using nevernull over traditional safeguarded access.
Detailed performance reports can be found here:
Node v7.1.0 Using Native Proxy
Node v6.0.0 Using Proxy Polyfill
Performance tests that generate the reports can be found here
Old API has been deprecated and is no longer supported. String selectors no longer are needed.
e.g.
//deprecated syntax
nn(person)('name.first');
nn(person)('name')('first');
Old API can be viewed and/or forked here
Thanks to inlineblock for their pull request to optimize performance by returning a cached nn(undefined) when the property value is undefined.
API now provides the ability to safely set property values. If the target is undefined, set has no effect, and no error is thrown.