How Lodash updateWith Handles Missing Paths
In the Lodash JavaScript library, _.updateWith modifies
a property value at a specific path of an object using an updater
function, while providing a customizer callback to define how resolved
path segments are generated. When encountering missing paths along the
specified traversal route, _.updateWith creates the
necessary intermediate objects or arrays dynamically to ensure the path
exists before applying the updater function.
Default Creation Behavior
If intermediate elements along the specified path do not exist,
_.updateWith will generate them automatically based on the
property keys:
- Numeric keys (e.g.,
'[0]'or'0') cause the method to initialize missing segments as arrays. - String keys (e.g.,
'a'or'profile') cause the method to initialize missing segments as plain objects.
Once the complete path has been created, the final property value is
passed into the updater function. Because the target leaf
property did not previously exist, the updater receives
undefined as its argument and sets the property to whatever
value the updater returns.
const _ = require('lodash');
const object = {};
_.updateWith(object, 'users[0].details.age', (n) => (n ? n + 1 : 18));
console.log(object);
// Output: { users: [ { details: { age: 18 } } ] }In this example, users did not exist, so an array was
generated to satisfy [0]. Next, details did
not exist, so an object was created inside the array. Finally,
age evaluated to undefined in the updater
callback, defaulting the value to 18.
Customizing Missing Paths with the Customizer
The primary distinction between _.update and
_.updateWith is the fourth parameter: the
customizer function. When a missing path is encountered,
Lodash calls the customizer to determine how to create the
missing intermediate segment:
customizer(nsValue, key, nested)
nsValue: The current resolved value at the segment.key: The key of the current segment.nested: The parent object containing the current segment.
If the customizer returns a value, that value is used as
the intermediate object or collection. If the customizer
returns undefined, Lodash falls back to its default
behavior of generating either an array or a plain object.
const _ = require('lodash');
const object = {};
// Force missing segments to be initialized as Map instances instead of plain objects
_.updateWith(
object,
'nested.key',
() => 'final value',
(nsValue) => (_.isObject(nsValue) ? nsValue : new Map())
);
console.log(object.nested instanceof Map);
// Output: trueSummary of Execution Flow
- Lodash traverses each segment in the given path.
- If a segment does not exist, the
customizerfunction is invoked. - If the customizer returns a value, that value becomes the container for subsequent path segments.
- If the customizer returns
undefined(or is omitted), Lodash creates an array for numeric keys or an object for string keys. - Upon reaching the end of the path, the
updateris invoked with the existing leaf value (orundefinedif missing) and the returned value is written to the destination.