Safe-obj
Underscore helpers to make object accessors safe
I came (partly) from a Perl background where you could say $obj->{thing}->{another_thing}->{more_things}
, and it would not blow up even if $obj was totally empty. Similarly, you could say $obj->{thing}->{foo} = 'bar'
, even if $obj had no property called 'thing'. I don't miss everything about Perl, but I do miss that. In javascript, you'd have to say:
if obj && objthing && objthinganother_thing && objthinganother_thingmore_things // I want to die a little bit
So this module is basically auto-vivification for javascript.
Install
npm install safe-obj --save
Usage
Server
As of v1.0.0, this module works with both lodash and underscore, though it requires using _.safe(obj, path)
with lodash since _(obj).safe(path)
triggers lodash's chaining.
safe-obj
exports an object that can be mixed into underscore/lodash like this:
_;
that let's you access object properties with wild abandon.
Client
Additionally, as of v1.0.0, it works on the client side. If window._
is defined (i.e. lodash or underscore has been loaded), _.safe
will add an _safe
property to it, which you can mix in with _.mixin(_._safe)
.
On the client, just include the script after underscore or lodash:
and then mix it in:
API
Safe
Let's you access object properties (and array indices too!) regardless of whether they exist. If, at any point, a property returns undefined
(where calling another object accessor would blow up), safe
immediately just returns undefined
(or a default, if you provide one).
var obj = {} // returns undefinedvar innerProp = ; // returns [] - useful if you want to call array methods but don't want to check the typevar anotherProp = ;
Expand
Let's you assign to any arbitrarily deep and non-existent property on an object. Any non-existent properties are expanded into objects.
var obj = {} ; // obj now equals: {// foo: {// bar: {// baz: 'hello world'// }// }// }
Expand is likely to be finnicky (at the moment) with expanding arrays. It's untested, and my guess is that it will create object properties with numbers. Something like
property: 0: // more stuff
I'd like to make that work more as expected in a future release, but for now, don't expect it to work.
Ensure
Sets a path to a given value unless that path already has a value. Also allows an optional list of "disallowed" values.
var obj = foo: bar: 'baz' ; // This will have no effect on obj since 'foo.bar' already has a value; obj = foo: {}; // This will set obj.foo equal to { bar: 'a default value' }; obj = foo: bar: 'nope' ; // This says don't allow 'nope' as a value of foo.bar, thus it will use the default;
AllOf
Uses safe
to return true
if all the paths exist in the object or false
if any is missing.
var obj = foo: bar: 'baz' ; ; // returns false // or// _(obj).allOf(['foo.bar', 'hello.world']);
AnyOf
Like allOf
but returns true
if any of the paths exist.
var obj = foo: bar: 'baz' ; ; // returns true
NoneOf
Like allOf
and anyOf
but only returns true when none of the paths exist.
var obj = foo: bar: 'baz' ; ; // returns false