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 {Object | Array} object
|
||||||
* @param {Path} path
|
* @param {Path} path
|
||||||
* @param {*} value
|
* @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
|
* @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) {
|
if (path.length === 0) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const key = path[0]
|
||||||
|
const updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath)
|
||||||
|
|
||||||
if (!isObjectOrArray(object)) {
|
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)
|
return applyProp(object, key, updatedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,32 @@ describe('immutabilityHelpers', () => {
|
||||||
assert.throws(() => setIn(obj, ['a', 'b', 'c'], 4), /Path does not exist/)
|
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', () => {
|
it('setIn replace value with object should throw an exception', () => {
|
||||||
const obj = {
|
const obj = {
|
||||||
a: 42,
|
a: 42,
|
||||||
|
|
Loading…
Reference in New Issue