How to Query Objects with Lodash matchesProperty
Lodash's _.matchesProperty method simplifies querying
JavaScript objects by creating a function that performs a deep
comparison between a given object property and a specified value.
Instead of writing verbose callback functions to check object states
during filtering, searching, or mapping operations, developers can
supply a property path and an expected value. This article explains how
_.matchesProperty works, its syntax, and how it streamlines
object querying, nested property access, and array manipulation.
What is
_.matchesProperty?
The _.matchesProperty method generates a predicate
function—a function that evaluates an input object and returns
true or false. It accepts two arguments: the
path of the property to get, and the value to determine a match
against.
Syntax:
_.matchesProperty(path, srcValue)path: A string or array representing the property path (supports dot notation for nested fields).srcValue: The value to match against the property's resolved value.
Simplifying Predicates in Higher-Order Functions
In standard JavaScript, filtering an array of objects based on a property requires an inline arrow function:
const users = [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false },
{ id: 3, name: 'Charlie', active: true }
];
// Native JavaScript
const activeUsers = users.filter(user => user.active === true);Using _.matchesProperty, you can create a reusable
predicate:
const isActive = _.matchesProperty('active', true);
const activeUsers = _.filter(users, isActive);Because Lodash internally integrates this utility, many methods like
_.filter, _.find, _.some, and
_.every automatically interpret [key, value]
array shorthands as calls to _.matchesProperty:
// Lodash shorthand equivalent to _.matchesProperty('active', true)
const activeUsers = _.filter(users, ['active', true]);Querying Deeply Nested Properties
One of the most significant advantages of
_.matchesProperty is its built-in support for nested
property paths without triggering
TypeError: Cannot read property of undefined errors.
const orders = [
{ id: 101, customer: { profile: { tier: 'gold' } } },
{ id: 102, customer: { profile: { tier: 'silver' } } },
{ id: 103, customer: null }
];
// Querying nested properties safely
const goldOrders = _.filter(orders, _.matchesProperty('customer.profile.tier', 'gold'));
// Or using shorthand:
const silverOrders = _.filter(orders, ['customer.profile.tier', 'silver']);In plain JavaScript, safely accessing deeply nested values often
requires optional chaining
(order.customer?.profile?.tier === 'gold').
_.matchesProperty encapsulates this logic
declaratively.
Deep Equality Matching
_.matchesProperty uses deep comparison for object and
array values rather than strict reference identity
(===).
const inventory = [
{ item: 'Laptop', tags: ['electronics', 'work'] },
{ item: 'Desk', tags: ['furniture'] }
];
// Matches deep array contents, not array memory reference
const electronics = _.filter(
inventory,
_.matchesProperty('tags', ['electronics', 'work'])
);Key Benefits
- Readability: Replaces manual conditional blocks with declarative path-value definitions.
- Safety: Gracefully handles
nullorundefinedintermediate properties in nested paths. - Reusability: Predicates can be created once, assigned to a variable, and reused across different collections.
- Deep Comparison: Accurately compares complex objects and arrays without extra equality-checking logic.