By the end of this tutorial, you’ll use _.update() to transform nested values with an updater function at any path depth.
01
Core syntax
_.update(object, path, updater)
02
Updater fn
Receives current value; return the new one.
03
Mutates object
Modifies in place; returns same reference.
04
Path formats
Dot strings, key arrays, bracket notation.
05
update vs set
Function transform vs direct assign.
06
Common patterns
Toggle, increment, uppercase, filter.
Fundamentals
What Is _.update()?
_.update() is Lodash’s nested transform-and-write helper. You pass an object, a path, and an updater function; Lodash reads the current value at that path, calls your function with it, and assigns the return value back. It is like _.set(), but the new value is computed from the old one.
💡
When a function beats a literal
Use _.update() for toggles (v => !v), increments (n => n + 1), string transforms, and any write that depends on the existing value.
Use it for config toggles, nested counters, normalizing user input, and patching state trees. When you already know the final value, _.set() is simpler; when you need to derive it, reach for _.update().
Foundation
📝 Syntax
The signature is three arguments—object, path, and updater:
javascript
_.update(object, path, updater)
Syntax Rules
object — the object to modify (mutated in place).
path — dot string ("address.city"), array (["profile", "score"]), or bracket form ("users[0].name").
updater — (currentValue) => newValue. Receives the value at the path (or undefined if missing).
Return value — the same object reference (for chaining).
Missing paths — like _.set(), Lodash can create intermediate objects when assigning the updater’s result.
javascript
import update from "lodash/update";
const user = {
name: "John",
address: { city: "New York", country: "USA" }
};
update(user, "address.city", (city) => city.toUpperCase());
// user.address.city -> "NEW YORK"
_.set() assigns a literal; _.update() derives the new value from the old one.
javascript
const item = { price: 100 };
// set: you supply the final value
_.set(item, "price", 120);
// update: compute from current value
_.update(item, "price", (p) => p * 1.1);
console.log(item.price);
// -> 132 (120 * 1.1)
_.update() is the functional sibling of _.set(): instead of passing a final value, you pass a function that transforms the current one. It shines for toggles, counters, string normalization, and array replacements at nested paths.
Remember it mutates in place. When you need control over how missing paths are built, continue to _.updateWith().
Use updaters for toggles, increments, and value-derived writes
Handle undefined in updaters when paths may not exist yet
Clone before _.update() when immutability is required
Match path style with _.set() and _.get() across your codebase
Prefer _.set() when you already know the final literal value
❌ Don’t
Use _.update() to delete properties—use _.unset()
Assume it is immutable like spread-based state updates
Forget that the updater must return the new value
Mutate the incoming value inside the updater without returning a copy when needed
Reach for update when a simple _.set() one-liner suffices
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about _.update()
Use these when the new value depends on the old one.
5
Core concepts
🔄01
Updater fn
Transform value.
Core
⚠️02
Mutates
In-place write.
Important
🔀03
vs set
Fn vs literal.
Compare
🗃️04
Paths
Same as set/get.
Syntax
📈05
Patterns
Toggle, +1.
Use case
❓ Frequently Asked Questions
_.update() gets the current value at a nested path, passes it to an updater function, and assigns the updater's return value back at that path. The object is mutated in place and the same object reference is returned.
_.set() assigns a value you already have. _.update() invokes a function on the existing value first—ideal for toggles, increments, uppercase transforms, and other derived writes.
The current value at the path. If the path does not exist yet, the updater receives undefined—similar to how _.set() can create missing paths when you assign a result.
Yes. Like _.set() and _.unset(), it modifies the object you pass in. Clone first when immutability matters: _.update(_.cloneDeep(obj), path, fn).
The same formats as _.set() and _.get(): dot strings like address.city, bracket notation like users[0].name, or key arrays like ["profile", "score"].
Use _.updateWith() when you need a customizer to control how intermediate objects are created along the path—similar to the set/setWith relationship.
Did you know?
_.update() is shorthand for “read at path, transform, write back”—the functional counterpart to _.set(). Some tutorials incorrectly describe it as immutable; like set and unset, it mutates the object you pass in.