By the end of this tutorial, you’ll use Lodash’s _.propertyOf() to fix an object once and read many different paths from it— the mirror image of _.property().
01
Core Syntax
_.propertyOf(object)
02
Object first
Path varies later.
03
Dot paths
read('a.b')
04
Dynamic
Runtime path strings.
05
vs property
Opposite curry.
06
Safe missing
Returns undefined.
Fundamentals
What Is _.propertyOf()?
_.propertyOf(object) is an object-first reader factory. You pass the object once; Lodash returns a function that accepts a path and returns the value at that path on the fixed object. Think readFromUser('address.city') instead of repeating user.address.city or _.get(user, path) everywhere.
💡
Beginner tip — opposite of _.property()
_.property('name')(user) fixes the path. _.propertyOf(user)('name') fixes the object. Same nested read—different reuse pattern.
Reach for propertyOf when one record (user profile, config blob, API response) is queried at many paths over time—especially when those paths come from variables, UI column keys, or user input.
Foundation
📝 Syntax
Pass the object to query; call the returned function with a path:
javascript
_.propertyOf(object)
Syntax Rules
object — the value whose properties you will read (usually a plain object).
Return value — a function (path) => value bound to that object.
path on call — dot string ('address.city') or key array (['address','city']).
Missing paths — returns undefined; does not throw.
Not for plucking arrays — use _.property() with _.map when many objects share one path.
javascript
import propertyOf from "lodash/propertyOf";
const user = {
name: "John Doe",
address: { city: "New York", zipCode: "10001" },
};
const readFromUser = propertyOf(user);
readFromUser("address.city");
// "New York"
Cheat Sheet
⚡ Quick Reference
Task
Code pattern
Notes
Multi-path reader
const read = _.propertyOf(obj)
Object fixed
Read nested field
read('address.city')
Dot path
Array path
read(['address','city'])
Same result
Dynamic path var
read(columnKey)
Runtime path
Many objects, one path
_.property('name')
Use property
One-shot + default
_.get(obj, path, fallback)
No reusable fn
Returns
Function
Path reader
Fixes
Object
Path varies
Missing
undefined
No throw
Category
Util
Accessor
Reference
🧰 Parameters
Argument to _.propertyOf() and the reader it returns:
objectRequired
The object (or value) whose properties will be read on each call.
_.propertyOf(config)
returned fnReader
Accepts a path and returns the resolved value on the fixed object.
read('app.name')
path argOn invoke
Dot string or key array—same rules as _.property() and _.get().
read(['settings','theme'])
missingBehavior
Returns undefined when the path does not exist—check explicitly or use _.get with a default.
read('missing.key')
For many objects and one shared path, prefer _.property(path) as a _.map iteratee instead of wrapping each item with propertyOf.
Hands-On
Examples Gallery
Practical _.propertyOf() patterns with copy-ready code, sample output, and interactive Try It Yourself labs.
📚 Getting Started
Fix the user object and read several nested paths from it.
Example 1 — Read multiple paths from one user
Create one reader, then query city and zip without repeating the object.
Store readConfig once at startup; pass path strings from env keys or UI without re-wiring the object reference.
Example 5 — Missing paths return undefined (no throw)
Older tutorials claim propertyOf throws on missing keys—it does not. Check for undefined instead.
javascript
const user = {
address: { city: "New York" },
};
const read = _.propertyOf(user);
const country = read("address.country");
if (country === undefined) {
console.log("Country not available");
} else {
console.log(country);
}
// Country not available
📤 Console output:
Country not available
How It Works
For a default in one expression, use _.get(user, 'address.country', 'N/A') instead of the reader pattern.
🚀 Beyond the Basics
propertyOf vs property—pick the right curry order.
Example 6 — propertyOf vs property on collections
One object, many paths → propertyOf. Many objects, one path → property.
The old reference incorrectly used _.propertyOf('address.city') with users.map—that swaps the API. propertyOf takes an object; property takes a path.
Compare
📋 _.propertyOf vs related patterns
Topic
_.propertyOf()
_.property()
_.get()
obj?.a?.b
Fixes first
Object
Path
Both at once
Inline read
Returns
Path reader fn
Getter fn
Value immediately
Value immediately
Best for
Many paths, one obj
Many objs, one path
One-off + default
Simple optional chain
map iteratee
Rarely
Common
Awkward
Needs arrow fn
Example
_.propertyOf(o)('a.b')
_.property('a.b')(o)
_.get(o, 'a.b', 0)
o?.a?.b
🧠 How _.propertyOf() Works
1
Capture object
Lodash stores the object reference you passed in.
Setup
2
Return reader
A function that accepts a path on each call.
Factory
3
Resolve path
Walk the path on the fixed object and return the value (or undefined).
Read
=
🛠
Property value
The value at the supplied path on the captured object—call again with a different path anytime.
Important
📝 Notes
_.propertyOf(object) takes the object—not a path string. The path goes on the returned function.
Opposite of _.property(): property fixes path; propertyOf fixes object.
Missing paths return undefined—they do not throw (contrary to some outdated examples).
For plucking one field from many records, use _.map(list, _.property('name')), not propertyOf.
Dynamic UI example: const read = _.propertyOf(userData); read(columnKey) where columnKey is 'profile.email'.
Next in the series: _.range()—generate numeric sequences.
Wrap Up
Conclusion
_.propertyOf() is the object-first counterpart to _.property(). When one record is queried at many paths—configs, profiles, dynamic forms—it keeps access clean and path-driven without repeating the source object.
Remember the split: many objects, one path → property; one object, many paths → propertyOf; single read with default → get.
Use when path strings come from variables, columns, or settings keys
Check for undefined on optional nested fields
Pair with paths.map(read) to batch-read several keys from one object
Use _.property when mapping the same path across many objects
❌ Don’t
Pass a path to _.propertyOf()—that is _.property()
Use propertyOf as a _.map iteratee over user arrays for one field
Expect throws on missing keys—it returns undefined
Recreate the reader inside hot loops—build it once outside
Confuse with _.methodOf()—that binds methods, not property paths
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about _.propertyOf()
Use these points when the object is fixed and paths vary.
5
Core concepts
📦01
Object first
Path later.
Core
🔄02
Reader fn
Reusable.
Pattern
✅03
Dynamic paths
Runtime keys.
Usage
📝04
undefined
Missing = safe.
Behavior
🛠05
vs property
Opposite curry.
Compare
❓ Frequently Asked Questions
_.propertyOf(object) returns a new function. When you call that function with a path, Lodash reads that path on the fixed object and returns the value—like a reusable reader where the object is baked in and the path varies.
They are opposites in curry order. _.property(path) fixes the path: getCity(user). _.propertyOf(object) fixes the object: readFromUser('address.city'). Use property for many objects and one path; use propertyOf for one object and many paths.
A dot-path string like 'address.city' or an array of keys like ['address', 'city']. Same path formats as _.property() and _.get().
The reader returns undefined. Lodash does not throw—despite what some older examples suggest. Check for undefined or use _.get(object, path, defaultValue) when you need a fallback.
Not for plucking the same field from many objects—that is _.property('name') with _.map. propertyOf shines when one record (config, form model, API response) is queried at many different paths over time.
Use it for config lookups, dynamic form fields, table columns driven by path strings, or any time the object stays fixed while the property path changes at runtime.
Did you know?
_.propertyOf(object)(path) and _.property(path)(object) read the same nested value—they differ only in which argument you fix first. Pick based on whether your paths or your objects repeat in the calling code.