Skip to content

Commit 15aeaff

Browse files
committed
Issue-2-DefaultWhenNotFound Issue #2 - Add optional third paramater to act as default if object is not truthy, key is not truthy, or full keypath does not exist on the object
1 parent 8861035 commit 15aeaff

File tree

3 files changed

+57
-12
lines changed

3 files changed

+57
-12
lines changed

README.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# `dlv(obj, keypath)` [![NPM](https://img.shields.io/npm/v/dlv.svg)](https://npmjs.com/package/dlv) [![Build](https://travis-ci.org/developit/dlv.svg?branch=master)](https://travis-ci.org/developit/dlv)
22

3-
> Safely get a dot-notated path within a nested object.
3+
> Safely get a dot-notated path within a nested object, with ability to return a default if the full key path does not exist
44
55
### Why?
66

7-
Smallest possible implementation: only **120 bytes.**
7+
Smallest possible implementation: only **165 bytes.**
88

99
You could write this yourself, but then you'd have to write [tests].
1010

11-
Implementation is ripped directly from [preact].
12-
1311
Supports ES Modules, CommonJS and globals.
1412

1513
### Installation
@@ -19,22 +17,42 @@ Supports ES Modules, CommonJS and globals.
1917

2018
### Usage
2119

20+
`delve(object, keypath, [default])`
21+
2222
```js
2323
import delve from 'dlv';
2424

2525
let obj = {
2626
a: {
2727
b: {
2828
c: 1
29+
e: undefined
2930
}
3031
}
3132
};
3233

34+
//use string dot notation for keys
3335
delve(obj, 'a.b.c') === 1;
3436

37+
//or use an array key
38+
delve(obj, ['a', 'b', 'c']) === 1;
39+
3540
delve(obj, 'a.b') === obj.a.b;
3641

42+
//returns undefined if the full key path does not exist and no default is specified
3743
delve(obj, 'a.b.c.d') === undefined;
44+
45+
//optional third parameter for default if the full key in path is missing
46+
delve(obj, 'a.b.c.d', 'foo') === 'foo';
47+
48+
//default is only used if full keypath does not exist.
49+
//Non-truthy values are still returned if they exist at the full keypath
50+
delve(obj, 'a.b.c.e', 'foo') === undefined;
51+
52+
//undefined obj or key returns undefined, unless a default is supplied
53+
delve(undefined, 'a.b.c') === undefined;
54+
delve(undefined, 'a.b.c', 'foo') === 'foo';
55+
delve(obj, undefined, 'foo') === 'foo';
3856
```
3957

4058
### License

index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
export default function dlv(obj, key) {
1+
export default function dlv(obj, key, def) {
2+
if(!obj || !key) return def;
23
if (key.split) key = key.split('.');
3-
for (var i=0; i<key.length && obj; i++) obj = obj[key[i]];
4-
return obj;
4+
var i=0, keyLength=key.length;
5+
for (; i<keyLength && obj.hasOwnProperty(key[i]); obj = obj[key[i++]]) ;
6+
return i===keyLength ? obj : def;
57
}

test.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ var assert = require('assert');
22
var delve = require('.');
33

44
var obj = {
5+
undef: undefined,
6+
zero: 0,
57
one: 1,
68
a: {
79
two: 2,
@@ -15,13 +17,17 @@ var obj = {
1517
};
1618

1719
// assert equality of a given path, as dot notation and array.
18-
function check(path, value) {
19-
assert.equal(delve(obj, path), value);
20+
//optional third argument is for default when object is not found
21+
function check(path, value, def) {
22+
23+
assert.equal(delve(obj, path, def), value);
2024
console.log(' ✓ delve(obj, "'+path+'")');
2125

22-
var arr = path.split('.');
23-
assert.equal(delve(obj, arr), value);
24-
console.log(' ✓ delve(obj, '+JSON.stringify(arr)+')');
26+
if(path) {
27+
var arr = path.split('.');
28+
assert.equal(delve(obj, arr, def), value);
29+
console.log(' ✓ delve(obj, '+JSON.stringify(arr)+')');
30+
}
2531
}
2632

2733
check('', undefined);
@@ -34,5 +40,24 @@ check('a.b.three', obj.a.b.three);
3440
check('a.b.c', obj.a.b.c);
3541
check('a.b.c.four', obj.a.b.c.four);
3642

43+
//test defaults
44+
check('', 'foo', 'foo');
45+
check('undef', undefined, 'foo');
46+
check('zero', 0, 'foo');
47+
check('a.badkey', 'foo', 'foo');
48+
check('a.badkey.anotherbadkey', 'foo', 'foo');
49+
50+
//check undefined key doesn't throw errors and uses default
51+
check(undefined, undefined);
52+
check(undefined, 'foo', 'foo');
53+
54+
//check undefined obj doesn't throw errors and uses default
55+
var backupObj = obj;
56+
obj = undefined;
57+
check('one', undefined);
58+
check('one', 'foo', 'foo');
59+
obj = backupObj;
60+
61+
3762
console.log('✅ Success!');
3863
process.exit(0);

0 commit comments

Comments
 (0)