Skip to content

Commit aab63c2

Browse files
committed
feat: support setting values
1 parent 0dca1f4 commit aab63c2

File tree

4 files changed

+118
-4
lines changed

4 files changed

+118
-4
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
undefsafe
2-
=========
1+
# undefsafe
32

43
Simple *function* for retrieving deep object properties without getting "Cannot read property 'X' of undefined"
54

5+
Can also be used to safely set deep values.
6+
67
## Usage
78

89
```js
@@ -21,3 +22,19 @@ console.log(undefsafe(object, 'a.b.not.found')); // undefined
2122
```
2223

2324
Demo: [https://jsbin.com/eroqame/3/edit?js,console](https://jsbin.com/eroqame/3/edit?js,console)
25+
26+
## Setting
27+
28+
```js
29+
var object = {
30+
a: {
31+
b: [1,2,3]
32+
}
33+
};
34+
35+
// modified object
36+
var res = undefsafe(object, 'a.b.0', 10);
37+
38+
console.log(object); // { a: { b: [10, 2, 3] } }
39+
console.log(res); // 1 - previous value
40+
```

lib/undefsafe.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict';
22

3-
function undefsafe(obj, path) {
3+
function undefsafe(obj, path, value) {
44
var parts = path.split('.');
55
var key = null;
66
var type = typeof obj;
7+
var parent = obj;
78

89
// we're dealing with a primative
910
if (type !== 'object' && type !== 'function') {
@@ -13,6 +14,7 @@ function undefsafe(obj, path) {
1314
}
1415

1516
while ((key = parts.shift())) {
17+
parent = obj;
1618
obj = obj[key];
1719
if (obj === undefined || obj === null) {
1820
break;
@@ -23,11 +25,14 @@ function undefsafe(obj, path) {
2325
// if it's not (i.e. parts has a length) then give undefined back.
2426
if (obj === null && parts.length !== 0) {
2527
obj = undefined;
28+
} else if (value) {
29+
key = path.split('.').pop();
30+
parent[key] = value;
2631
}
2732

2833
return obj;
2934
}
3035

3136
if (typeof module !== 'undefined') {
3237
module.exports = undefsafe;
33-
}
38+
}

test/array.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
var test = require('tap').test;
3+
var undefsafe = require('../lib/undefsafe');
4+
5+
test('get specific array index', function (t) {
6+
var fixture = {
7+
a: [1,2,3,4]
8+
};
9+
10+
var res = undefsafe(fixture, 'a.2');
11+
t.equal(res, 3);
12+
t.end();
13+
});
14+
15+
test('set specific array index', function (t) {
16+
var fixture = {
17+
a: [1,2,3,4]
18+
};
19+
20+
undefsafe(fixture, 'a.2', 30);
21+
t.deepEqual(fixture, { a: [1,2,30,4] });
22+
t.end();
23+
});
24+

test/set.test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
var test = require('tap').test;
3+
var undefsafe = require('../lib/undefsafe');
4+
5+
test('setting deep object values', function (t) {
6+
var fixture = {
7+
a: {
8+
b: {
9+
c: {
10+
d: 10
11+
}
12+
}
13+
}
14+
};
15+
16+
undefsafe(fixture, 'a.b.c.d', 20);
17+
t.equal(fixture.a.b.c.d, 20, 'deep primative changed');
18+
t.end();
19+
});
20+
21+
test('setting shallow object values', function (t) {
22+
var fixture = {
23+
a: {
24+
b: {
25+
c: {
26+
d: 10
27+
}
28+
}
29+
}
30+
};
31+
32+
undefsafe(fixture, 'a.b', 20);
33+
t.equal(fixture.a.b, 20, 'shallow object changed');
34+
t.end();
35+
});
36+
37+
test('undef value', function (t) {
38+
var fixture = {
39+
a: {
40+
b: {
41+
c: {
42+
d: undefined
43+
}
44+
}
45+
}
46+
};
47+
48+
undefsafe(fixture, 'a.b', 20);
49+
t.deepEqual(fixture.a.b, 20, 'swapped undefined');
50+
t.end();
51+
});
52+
53+
test('missing value', function (t) {
54+
var fixture = {
55+
a: {
56+
b: {
57+
c: {
58+
d: 10
59+
}
60+
}
61+
}
62+
};
63+
64+
var res = undefsafe(fixture, 'a.c', 20);
65+
t.equal(res, undefined, 'target was not found');
66+
t.deepEqual(fixture.a.b, { c: { d: 10 } }, 'shallow object changed');
67+
t.end();
68+
});

0 commit comments

Comments
 (0)