Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Merge a value by a dot path.
> The target value must be an object, array, null, or undefined.

* If target is an object, Object.assign({}, target, param) is used.
* If target an array, target.concat(param) is used.
* If target an array, target.concat(param) is used, unless an index is given in the opts param.
* If target is null or undefined, the value is simply set.

```javascript
Expand All @@ -193,6 +193,10 @@ var arr = {foo: { bar: [1, 2] } };
// merge array
dotProp.merge(arr, 'foo.bar', [3, 4] );
//=> {foo: { bar:[1, 2, 3, 4 ] }

// merge array at index
dotProp.merge(arr, 'foo.bar', [1.5, 1.6], {index: 1} );
//=> {foo: { bar:[1, 1.5, 1.6, 2, 3, 4 ] }
```
## License

Expand Down
18 changes: 15 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,29 @@ module.exports.toggle = function(obj, prop) {
/**
* Merges a value. The target value must be an object, array, null, or undefined.
* If target is an object, Object.assign({}, target, param) is used.
* If target an array, target.concat(param) is used.
* If target an array, target.concat(param) is used, unless an index is given in the opts param.
* If target is null or undefined, the value is simply set.
* @param obj The object to evaluate.
* @param prop The path to the value.
* @param val The value to merge into the target value.
* @param opts Options for the merge:
* <li> index: if merging into an array,
* insert at the specified index (if it is a valid index) instead of appending.
*/
module.exports.merge = function(obj, prop, val) {
module.exports.merge = function(obj, prop, val, opts={}) {
var curVal = this.get(obj, prop);
if (typeof curVal === 'object') {
if (Array.isArray(curVal)){
return this.set(obj, prop, curVal.concat(val));
if (typeof opts.index === 'number') {
if (opts.index >= 0 && opts.index <= curVal.length) {
const newList = curVal.slice(0, opts.index).concat(val).concat(curVal.slice(opts.index));
return this.set(obj, prop, newList);
} else{
return obj;
}
} else {
return this.set(obj, prop, curVal.concat(val));
}
} else if (curVal === null){
return this.set(obj, prop, val);
}
Expand Down
70 changes: 70 additions & 0 deletions test/dot-prop-immutable-merge.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,76 @@ describe('dot-prop-immutable.merge.spec.js', function () {

});


describe('merge an array value into array with index', () => {

before(function () {
result = dotProp.merge(obj, 'c', [3, 4], {index: 1});
});

it('should merge prop', () => {
expect(result).to.eql({
a: 1,
b: {
x: 1,
y: 2
},
c: [1, 3, 4, 2],
d: null,
'b.x': 10
});
});

it('invariant', objInvariant);

});

describe('merge an array value into array with index at end', () => {

before(function () {
result = dotProp.merge(obj, 'c', [3, 4], {index: 2});
});

it('should merge prop', () => {
expect(result).to.eql({
a: 1,
b: {
x: 1,
y: 2
},
c: [1, 2, 3, 4],
d: null,
'b.x': 10
});
});

it('invariant', objInvariant);

});

describe('merge an array value into array with index out of bounds', () => {

before(function () {
result = dotProp.merge(obj, 'c', [3, 4], {index: 3});
});

it('should merge prop', () => {
expect(result).to.eql({
a: 1,
b: {
x: 1,
y: 2
},
c: [1, 2],
d: null,
'b.x': 10
});
});

it('invariant', objInvariant);

});

describe('merge an object value into null', () => {

before(function () {
Expand Down