dotted
v0.1.1
Published
Nested and Delegating Accessors and Utilities
Downloads
280
Maintainers
Readme
dotted.js
Nested and delegating object-graph utilities.
var dotted = require('dotted');
// ohai, some tweets
var tweets = {
"requested_at": "Thu Oct 09 09:50:20 +0000 2014",
"items": [
{
"id": 516626496845131800,
"created_at": "Mon Sep 29 16:32:09 +0000 2014",
"text": "the other thing that happens when you do something for 10,000 hours is you develop a really refined hatred for it",
"user": {
"id": 16142493,
"screen_name": "me_irl",
"name": "the government man"
},
"retweet_count": 55,
"favorite_count": 79
}, {
"id": 516596160208076800,
"created_at": "Mon Sep 29 14:31:37 +0000 2014",
"text": "It's Piketty week, and someone in my Economic Justice class is wearing a 'r>g' shirt. <3",
"user": {
"id": 19530289,
"screen_name": "PennyRed",
"name": "Laurie Penny"
},
"retweet_count": 6,
"favorite_count": 18
}, {
"id": 516438947367358460,
"created_at": "Mon Sep 29 04:06:54 +0000 2014",
"text": "finding out an “indie” site has VC funding is the Internet version of learning your Marxist urban poet friend has a trust fund",
"user": {
"id": 55525953,
"screen_name": "Pinboard",
"name": "Pinboard"
},
"retweet_count": 190,
"favorite_count": 206
}
],
"notes": {
"cRaZy.note": "completely unreasonable"
}
};
// funny stuff.
// but we have some srs bsns to attend to.
dotted.getNested(tweets, 'items.1.user.screen_name') // => 'PennyRed'
// Array indices are fine, as all keys are strings in JS
dotted.setNested(tweets, 'flags.reviewed', true)
// No error is thrown, but...
dotted.getNested(tweets, 'flags.reviewed') // => undefined
// The fact that `flags` doesn't exist prevents `reviewed` from being set.
// The `ensure` option will fix it.
dotted.setNested(tweets, 'flags.reviewed', 'twice!', { ensure:true })
dotted.getNested(tweets, 'flags.reviewed') // => 'twice!'
// Ahh, much better.
// Note dotted also accepts Arrays in place of dotted keys -- this helps us
// deal with cRaZy keys with dots in them:
dotted.getNested(tweets, ['notes', 'cRaZy.note']) // => 'completely unreasonable'
Word.
Usage
For usage in node.js, install it via npm:
npm install dotted
For the client side, I'm a fan of [browserify][browserify] to get my require
on.
When there isn't a require
about, dotted
will simply install itself at window.dotted
.
It's up to you how you get it on the page -- you can download a dotted.js dist (old school);
or install via a random client-side package-manager (crazy):
bower install dotted
component install dsc/dotted
dotted
presently depends on a _
library, so get lodash (or underscore)
on the page as well. You can mix dotted
into _
, if you wish, for convenience and chaining:
var _ = require('lodash');
_.mixin(dotted);
This dependency is ugly, but for now dotted
will attempt to require a _
library if it can,
and fall back to window._
/ globals._
. It yells if both fail. Anyway, even once that's
cleaned up, dotted
will still play nicely with others -- as a mixin and standalone.
API
Options
Many accessor functions take an options object with common fields. The sub-object
delegation options (getter
, setter
, and deleter
) are used to specify where
to look for the specific accessor method on a custom sub-object when performing
that operation. (Functions that do not use that operation will ignore these
options, so you're welcome to specify them everywhere just to be safe.)
| name | type | default | description |
| ----------- | --------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| getter | String
| "get"
| Name of the sub-object getter method to delegate to (if it exists). |
| setter | String
| "set"
| Name of the sub-object setter method to delegate to (if it exists). |
| deleter | String
| "delete"
| Name of the sub-object deleter method to delegate to (if it exists). |
| ensure | Boolean
| false
| If true, intermediate keys that are null
or undefined
will be filled in with a new empty object {}
, ensuring the get will return valid metadata. |
Delegating Accessors
dotted.get(target, key, def, options) -> value
Gets the value at key
from the object if present, returning def
otherwise.
dotted.set(target, key, value, options) -> target
Puts a given value to key
on the given target object. If an object is supplied as key
instead of a String,
each key-value pair on that object will be put to the target object. In this case, omit value
. Returns the
target object.
dotted.delete(target, key, options) -> oldValue
Deletes key
from the target object, returning whatever value was present prior to being removed.
Nested Delegating Accessors
These methods perform nested accessor operations, delegating like their non-nested counterparts to the target object when an instance method is found matching the operation.
dotted.getNested(target, chain, def, options) -> value
Searches a hierarchical object for a given subkey specified in dotted-property syntax, returning the value
if found, and def
otherwise.
dotted.setNested(target, chain, value, options) -> oldValue
Searches a hierarchical object for a given subkey specified in dotted-property syntax, setting it with the provided value if found.
dotted.deleteNested(target, chain, options) -> target
Searches a hierarchical object for a potentially-nested key and removes it, returning whatever value was previously there prior to removal.
Aliases: unsetNested
.
dotted.getNestedMeta(object, chain, options) -> Object
[Private] Searches a hierarchical object for a given subkey (specified in dotted-property syntax),
respecting sub-object accessor-methods (e.g., 'get', 'set') if they exist. If found, returns an object
of the form { key: Qualified key name, obj: Parent object of key, val: Value at obj[key], opts: Options }
,
and otherwise undefined
.
Feedback
Find a bug or want to contribute? Open a ticket (or fork the source!) on github. You're also welcome to send me email at [email protected].
Development
This project is written in Coco, a dialect of CoffeeScript -- both of which compile down to plain JavaScript. Coco and Coffee are quite similar, except for a few things. (Things which, imo, make Coco vastly more pleasant to work in). If you can read JavaScript (or Ruby, really), you'll find Coco/Coffee familiar.
(I refer to the CoffeeScript docs for the syntax, and I find the comparison page to be the best reference for Coco.)
Coco requires compilation before it'll run in the browser (though node can run it directly --
#!/usr/bin/env coco
will work as a shebang as well). I wrote request middleware that recompiles stale files on demand, and it is pretty cool.
--
dotted
was written by David Schoonover; it is open-source software and
freely available under the MIT License.