How Lodash _.at Retrieves Values from Complex Paths

The _.at method in the Lodash JavaScript library creates an array of values corresponding to specified paths within a collection or object. Instead of requiring developers to write repetitive accessor logic or chain multiple optional chaining operators, _.at accepts an object along with one or more path strings or arrays. It parses these paths, navigates through nested properties and arrays, and collects the matching values into a single flattened array, returning undefined for any path that does not exist.

Syntax and Core Mechanics

The basic syntax for the method is:

_.at(object, [paths])

Under the hood, _.at uses Lodash's internal path parsing mechanism (similar to _.get). It treats property paths as structured access instructions, transforming complex string representations into a sequence of keys to retrieve nested data safely.

Handling Path Formats

The _.at method can interpret several different path formats:

When a string path like 'users[0].posts[1].title' is passed to _.at, Lodash decomposes the string into a traversal chain: ['users', '0', 'posts', '1', 'title']. It then iterates through this chain sequentially against the target object.

Safe Navigation and Missing Keys

A key benefit of _.at is safe navigation. In standard JavaScript, attempting to read a deeply nested property on an undefined or null intermediate object throws a runtime error (e.g., TypeError: Cannot read properties of undefined).

The _.at method short-circuits traversal as soon as an intermediate reference evaluates to null or undefined. Instead of throwing an error, it returns undefined at the corresponding index in the output array.

Practical Example

The following example demonstrates retrieving multiple values from deeply nested structures using a mix of notation styles:

const _ = require('lodash');

const data = {
  store: {
    name: "Tech Central",
    inventory: [
      { id: 101, name: "Keyboard", specs: { wireless: true, price: 49.99 } },
      { id: 102, name: "Mouse", specs: { wireless: false, price: 19.99 } }
    ]
  },
  location: {
    coordinates: [37.7749, -122.4194]
  }
};

const results = _.at(data, [
  'store.name',
  'store.inventory[0].specs.price',
  'store.inventory[1].name',
  'location.coordinates[0]',
  'store.inventory[5].name' // Non-existent index
]);

console.log(results);
// Output: [ 'Tech Central', 49.99, 'Mouse', 37.7749, undefined ]

Difference Between _.at and _.get

While _.get focuses on retrieving a single value with an optional default fallback, _.at is designed to extract multiple values at once. You can think of _.at as mapping an array of _.get calls over the target object, streamlining bulk extraction from complex and irregularly shaped data structures.