Lodash Seq — sequence & chaining
What you’ll learn
- What to know before you start (see Prerequisites).
- How _.chain() and _(value) wrap data for fluent pipelines.
- When to use _.tap() (side effects) versus _.thru() (transform).
- Why .value() is required to unwrap a chain and get a plain result.
- Where each Seq method maps on this site (
/lodash/seq/...).
Prerequisites
Comfort with _.map(), _.filter(), and other Lodash helpers you plan to chain. Optional familiarity with Object methods when pipelines reshape plain objects.
- Method chaining concept: each step receives the output of the previous step (or the same value for
tap). - Lodash imports: chaining requires the full wrapper—typically
import _ from "lodash"orimport chain from "lodash/chain"plus related methods. - Return values: know whether a Lodash method mutates in place or returns a new value—both work in chains but affect debugging.
Key concepts
Lodash Seq is about how you call other Lodash methods—not a separate data type. A wrapper holds your value, exposes chainable versions of helpers, and waits for .value() before returning plain JavaScript data.
Wrapper object
_.chain(x) returns a Lodash wrapper—not the transformed data until you unwrap.
Fluent pipeline
Read top-to-bottom: map, filter, pick, groupBy—each step feeds the next.
tap vs thru
tap for logging or metrics; thru when the step must change the value type.
Unwrap
.value() terminates the chain and returns the final result.
Overview
Seq methods sit at the edges of a pipeline—starting a chain, peeking with side effects, or routing through a custom function—while Array, Collection, and Object methods do the heavy data work in the middle.
Start
_.chain or _(value) wraps input once.
Observe
tap logs or records metrics without altering flow.
Transform
thru plus any chainable Lodash method in between.
⚖️ Chaining vs plain Lodash calls
Lodash chaining reads well for multi-step data pipelines. For one or two operations, nested calls or native array methods are often shorter and tree-shake more easily.
| Situation | Prefer plain calls | Consider chaining |
|---|---|---|
| Single map or filter | _.filter(_.map(x, fn), pred) | Usually unnecessary |
| 3+ sequential Lodash steps | Nested calls get hard to read | _.chain(x).map(...).filter(...).value() |
| Debug logging mid-pipeline | Temp variables | .tap(v => console.log(v)) |
| Custom transform between steps | Assign to a variable | .thru(arr => ...) |
| Bundle size matters | Per-method imports | Full lodash or chain bundle often larger |
Install and import
Chaining typically imports the main Lodash entry or chain plus the methods you call in the pipeline.
npm install lodash import _ from "lodash";
const data = [1, 2, 3, 4, 5];
const result = _.chain(data)
.map(function (x) { return x * 2; })
.filter(function (x) { return x > 5; })
.value();
// result -> [6, 8, 10] tap and thru in a chain
tap inspects without changing the value; thru replaces it with the function return value.
const users = [
{ name: "Ada", active: true },
{ name: "Bob", active: false }
];
const names = _.chain(users)
.filter("active")
.tap(function (list) { console.log("active count:", list.length); })
.thru(function (list) { return _.map(list, "name"); })
.value();
// names -> ["Ada"] Unwrap with .value()
Without .value(), you hold a wrapper object—not the array or object you expect.
const wrapped = _.chain([1, 2, 3]).map(function (n) { return n + 1; });
console.log(Array.isArray(wrapped)); // -> false
const plain = wrapped.value();
console.log(plain); // -> [2, 3, 4] 🔄 Wrapper vs unwrapped results
Every chain step returns another wrapper until you call .value(), .valueOf(), or Symbol.iterator (for lazy next iteration).
| Call | Returns | Rule of thumb |
|---|---|---|
_.chain(x) | Wrapper | Start of pipeline. |
.map / .filter / ... | Wrapper | Chain continues. |
.tap(fn) | Wrapper (same inner value) | Side effects only. |
.thru(fn) | Wrapper (new inner value) | Value may change type. |
.value() | Plain JavaScript value | Always finish here in app code. |
Suggested learning path
Walk these in order once individual Seq tutorials are published on CodeToFun.
💻 Environment and versions
- Lodash 4.x: the index below reflects the Seq surface shipped with
lodash@^4. - Browsers & Node: chaining works identically; bundlers may pull a larger chunk when using
_.chain. - TypeScript: wrapper types are loose—annotate final results after
.value()when strict typing matters.
Top-level Seq methods
URLs follow /lodash/seq/{method-kebab} (for example /lodash/seq/chain).
| Method | What it does |
|---|---|
_.chain() | Wrap a value in a Lodash sequence so collection/array/object methods chain fluently; finish with .value(). |
_.tap() | Run a side-effect function on the current value, then pass the original value through unchanged. |
_.thru() | Pass the current value through a function and continue the chain with the return value. |
Wrapper & prototype helpers
These live on the object returned by _.chain()—documented under /lodash/seq/prototype/... as tutorials are added.
| Method | What it does |
|---|---|
_(value) / lodash() | Shorthand entry point—wrap a value the same way as _.chain() to start a sequence. |
Wrapper prototype | Methods on the chain wrapper: value, commit, plant, next, reverse, and more. |
_.value() | Execute the chain and return the unwrapped result (alias valueOf). |
_.commit() | Execute pending chain actions and return the wrapper for hybrid chaining. |
_.plant() | Create a clone of the chain with a new wrapped value at the same pipeline stage. |
_.next() | Advance lazy iteration on wrapped sequences (iterator protocol). |
_.reverse() | Reverse the wrapped array in place inside the chain. |
_.at() | Apply a function at a specific index or path within the chain context. |
Pitfalls to avoid
Forgetting .value()
A chain without .value() looks like data but is a wrapper—common source of “why isn’t this an array?” bugs.
Expecting stream-style laziness
General _.chain pipelines run eagerly when unwrapped—they defer extraction, not infinite lazy evaluation.
Importing all of Lodash for one chain
Per-method imports avoid wrapper overhead when you only need map and filter once.
❓ FAQ
Summary
- Scope: Seq is Lodash’s chaining layer—wrap, transform with other Lodash methods, unwrap with
.value(). - tap vs thru: observe without changing vs pass through a transforming function.
- Next steps: open Lodash _.chain(), revisit _.valuesIn(), or pick any row in the index.
The most common chain bug is forgetting .value()—_.chain([1,2,3]).map(n => n * 2) returns a wrapper object, not an array. Call .value() (or .valueOf()) to unwrap.
9 people found this page helpful
