immutable-object-update
Simple and fast immutable update utility.
- full documentation can be found on https://andres-kovalev.github.io/immutable-object-update/
Description
immutable-object-update
provides simple utilities for immutable object update (pretty helpful for reducers).
Installation
As any other npm package immutable-object-update
can be added to your project by following command:
npm i -S immutable-object-update
API
There are several operations provided by this package:
- filter(object, path, predicate)
- get(object, path)
- insert(object, path, value)
- insertAll(object, path, values)
- map(object, path, transform)
- pop(object, path)
- popN(object, path, n)
- push(object, path, value)
- pushAll(object, path, values)
- reduce(object, path, reducer)
- remove(object, path)
- removeN(object, path, n)
- set(object, path, value)
- shift(object, path)
- shiftN(object, path, n)
- unshift(object, path, value)
- unshiftAll(object, path, values)
- update(object, path, update)
Most of operations consumes at least 2 arguments:
object
to be updatedpath
to updated element
The 2nd argument might be an array of items or dot-separated string.
import { set } from 'immutable-object-update';
const state = {
a: {
a1: 1,
a2: 2
},
b: {
b1: 3,
b2: 4
}
};
const updated = set(state, [ 'b', 'b1' ], 5);
// or
const updated = set(state, 'b.b1', 5);
As a result we will receive new object with structure below:
{
a: {
a1: 1,
a2: 2
},
b: {
b1: 3,
b2: 5
}
}
New object will keep the same refs when necessary:
state === updated // false
state.a === updated.a // true (structure of a hasn't changed)
state.a.a1 === updated.a.a1 // true
state.a.a2 === updated.a.a2 // true
state.b === updated.b // false
state.b.b1 === updated.b.b1 // true
state.b.b2 === updated.b.b2 // false
When using string as 2nd argument - dot will be considered as a delimiter (e.g. a.b
means field b
of field a
). So, it's not possible to update keys which contains dots with string type path:
const updated = set({
'a.b': 1,
a: {
b: 2
}
}, 'a.b', 3);
/*
{
'a.b': 1,
a: {
b: 3
}
}
*/
If you need to update such keys, use array type path instead:
const updated = set({
'a.b': 1,
a: {
b: 2
}
}, [ 'a.b' ], 3);
/*
{
'a.b': 3,
a: {
b: 2
}
}
*/
Utility also ignores empty path (e.g. a..b
equal to a.b
) and will create intermediate fields by itself when needed:
const updated = set({}, 'a.b', 10);
/*
{
a: {
b: 10
}
}
*/
It can even create new objects when no source object provided:
const updated = set(undefined, 'a.b', 10);
/*
{
a: {
b: 10
}
}
*/
It tries to predict type of created object. For instance, when path contains number, array will be created:
const updated = set({}, 'a.0', 1);
/*
{
a: [ 1 ]
}
*/
To prevent further accidental mutation all operations returns frozen updated object.
const updated = set(source, 'b.b1', 6);
updated.b.b1 = 10; // updated.b.b1 still has value of 6
Partial application
All operations supports partial application - when object arguments is not provided, operation returns update function:
const setB1to6 = set('b.b1', 6);
const updated = setB1to6(state); // equal to set(state, 'b.b1', 6);
When partial application is used, updated object should be passed last:
const setB1 = set('b.b1');
const setB1to6 = setB1(6); // equal to set('b.b1', 6);
There are several helpful functions provided to make work with partially applied operations easier: