Extend `setIn` with optional support for creating missing path
This commit is contained in:
parent
b9ceec09e3
commit
ad4572d21e
|
@ -94,19 +94,35 @@ export function getIn (object, path) {
|
|||
* @param {Object | Array} object
|
||||
* @param {Path} path
|
||||
* @param {*} value
|
||||
* @param {boolean} [createPath=false]
|
||||
* If true, `path` will be created when (partly) missing in
|
||||
* the object. For correctly creating nested Arrays or
|
||||
* Objects, the function relies on `path` containing a number
|
||||
* in case of array indexes.
|
||||
* If false (default), an error will be thrown when the
|
||||
* path doesn't exist.
|
||||
* @return {Object | Array} Returns a new, updated object or array
|
||||
*/
|
||||
export function setIn (object, path, value) {
|
||||
export function setIn (object, path, value, createPath = false) {
|
||||
if (path.length === 0) {
|
||||
return value
|
||||
}
|
||||
|
||||
const key = path[0]
|
||||
const updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath)
|
||||
|
||||
if (!isObjectOrArray(object)) {
|
||||
throw new Error('Path does not exist')
|
||||
if (createPath) {
|
||||
const newObject = typeof key === 'number'
|
||||
? []
|
||||
: {}
|
||||
newObject[key] = updatedValue
|
||||
return newObject
|
||||
} else {
|
||||
throw new Error('Path does not exist')
|
||||
}
|
||||
}
|
||||
|
||||
const key = path[0]
|
||||
const updatedValue = setIn(object[key], path.slice(1), value)
|
||||
return applyProp(object, key, updatedValue)
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,32 @@ describe('immutabilityHelpers', () => {
|
|||
assert.throws(() => setIn(obj, ['a', 'b', 'c'], 4), /Path does not exist/)
|
||||
})
|
||||
|
||||
it.only('setIn non existing path with createPath=true', () => {
|
||||
const obj = {}
|
||||
|
||||
assert.deepStrictEqual(setIn(obj, ['a', 'b', 'c'], 4, true), {
|
||||
a: {
|
||||
b: {
|
||||
c: 4
|
||||
}
|
||||
}
|
||||
})
|
||||
assert.deepStrictEqual(obj, {})
|
||||
})
|
||||
|
||||
it('setIn non existing path with createPath=true and nested array', () => {
|
||||
const obj = {}
|
||||
|
||||
assert.deepStrictEqual(setIn(obj, ['a', 2, 'c'], 4, true), {
|
||||
a: [
|
||||
,
|
||||
,
|
||||
{ c : 4 }
|
||||
]
|
||||
})
|
||||
assert.deepStrictEqual(obj, {})
|
||||
})
|
||||
|
||||
it('setIn replace value with object should throw an exception', () => {
|
||||
const obj = {
|
||||
a: 42,
|
||||
|
|
Loading…
Reference in New Issue