Curried property accessor function that resolves deeply-nested object properties via dot/bracket-notation string path while mitigating
TypeErrors
via friendly and composable API.
yarn add selectn
or
npm install selectn --save
or
<script src="https://unpkg.com/selectn/selectn.min.js"></script>
The browsers listed in .zuul.yml are continuously tested; however,
selectn
is also known to work on older unlisted legacy browsers.
person && person.info && person.info.name && person.info.name.full
selectn('info.name.full', person)
contacts.map(function (contact) {
return contact && contact.addresses && contact.addresses[0]
})
contacts.map(selectn('addresses[0]')))
- Mitigate boilerplate guards like
if (obj && obj.a && obj.a.b && obj.a.b.c)
. - Mitigate TypeError
Cannot read property '...' of undefined
. - Multiple levels of array nesting:
'group[0].section.a.seat[3]'
. - Dashed key access:
'stats.temperature-today'
. - When the value at the given path is a function, it is invoked and the functions returned value is returned.
selectn
is auto-curried so partial application is automatic when you omit the second argument.selectn
uses Haskell style parameter order (AKA: data-last) which enables pointfree style programming.- Functions returned by
selectn
are higher-order property accessors which can be passed to other higher-order functions like map or filter. - Compatible with modern and legacy browsers, Node/CommonJS, and AMD.
- No eval or Function (see:
eval
in disguise). - No typeof since, typeof is not a real solution to this problem but can appear to be due to the way the global scope is implied.
Avoid annoying Cannot read property '...' of undefined
TypeError
without writing boilerplate anonymous functions or guards.
var selectn = require('selectn')
var language = [
{ strings: { en: { name: 'english' } }},
{ strings: { es: { name: 'spanish' } }},
{ strings: { km: { name: 'khmer' } }},
{ strings: { es: { name: 'spanish' } }},
{ nodatas: {}}
]
var spanish = selectn('strings.es')
//=> [Function]
language.filter(spanish).length
//=> 2
Access deeply nested properties (including dashed properties) using point-free style.
var selectn = require('selectn')
var data = {
client: {
message: { 'message-id': 'd50afb80-a6be-11e2-9e96-0800200c9a66' }
}
}
var getId = selectn('client.message.message-id')
//=> [Function]
Promise.resolve(data).then(getId)
//=> 'd50afb80-a6be-11e2-9e96-0800200c9a66'
Avoid wrapping property accessors in anonymous functions.
var selectn = require('selectn')
var contacts = [
{ addresses: [ '123 Main St, Broomfield, CO 80020', '123 Main St, Denver, CO 80202' ] },
{ addresses: [ '123 Main St, Kirkland, IL 60146' ] },
{ phones: [] },
]
var primaryAddress = selectn('addresses[0]')
//=> [Function]
contacts.map(primaryAddress)
//=> [ '123 Main St, Broomfield, CO 80020', '123 Main St, Kirkland, IL 60146', undefined ]
Pass an array as path instead of a string.
var selectn = require('selectn')
var data = {
client: {
'message.id': 'd50afb80-a6be-11e2-9e96-0800200c9a66'
}
}
selectn(['client', 'message.id'], data)
//=> 'd50afb80-a6be-11e2-9e96-0800200c9a66'
Avoid
var fn = data.may.be.a.fn; if (typeof fn === 'function') fn()
.
var selectn = require('selectn')
function hi () { return 'hi' }
var data = { may: { be: { a: { fn: hi } } } }
selectn('may.be.a.fn', data)
//=> 'hi'
path (String|Array)
Dot/bracket-notation string path or array.
(Function)
Unary function accepting the object to access.
path (String|Array)
Dot/bracket-notation string path or array.object (String|Array)
Object to access.
(*|undefined)
Value at path if path exists orundefined
if path does not exist.
selectn
has inspired ports to other languages:
Language | Project |
---|---|
Python | selectn |
Other JS packages whose friendly API is driven by selectn
:
JS packages that have inspired selectn
:
Alternative packages you might like instead of selectn
: