How to Use the Lodash _.wrap Method
The Lodash _.wrap method is a utility that enables
developers to encapsulate an existing function inside a wrapper
function, providing a clean mechanism for adding custom pre-execution
and post-execution logic. By supplying the target function as the first
argument to the wrapper, _.wrap facilitates argument
inspection, condition-based execution, and return value modification
without altering the original function's codebase.
Understanding the Syntax
The syntax for _.wrap is straightforward:
_.wrap(value, [wrapper=identity])value: The value or original function to wrap.wrapper: The function that encapsulates thevalue. It receives the original function as its first argument, followed by any arguments passed to the returned wrapped function.
When the wrapped function is executed, Lodash delegates the call to the wrapper, granting full control over when, how, or even if the original function is invoked.
Implementing Pre-Logic
Pre-logic refers to code that runs before the wrapped function is called. Common use cases include parameter validation, authentication checks, logging incoming parameters, or sanitizing inputs.
Because the wrapper receives the original function as its first argument and the caller's arguments as subsequent parameters, you can inspect or modify these inputs before forwarding them:
const _ = require('lodash');
function greet(name) {
return `Hello, ${name}!`;
}
const secureGreet = _.wrap(greet, function(originalFn, name) {
// Pre-logic: Validation
if (!name || typeof name !== 'string') {
return 'Hello, Guest!';
}
// Pre-logic: Input transformation
const capitalized = name.trim().toUpperCase();
// Calling the original function with modified arguments
return originalFn(capitalized);
});
console.log(secureGreet('alice ')); // "Hello, ALICE!"
console.log(secureGreet(null)); // "Hello, Guest!"Implementing Post-Logic
Post-logic runs after the original function has resolved. This is ideal for transforming output, logging execution metrics, caching results, or handling clean-up operations.
To implement post-logic, capture the return value of the original function inside the wrapper, execute your custom logic, and return the final processed value:
const _ = require('lodash');
function calculateTotal(subtotal, taxRate) {
return subtotal + (subtotal * taxRate);
}
const formattedTotal = _.wrap(calculateTotal, function(originalFn, subtotal, taxRate) {
// Execute the original logic
const total = originalFn(subtotal, taxRate);
// Post-logic: Format as currency string
return `$${total.toFixed(2)}`;
});
console.log(formattedTotal(100, 0.0825)); // "$108.25"Combining Pre- and Post-Logic
You can combine both steps into a single wrapper to create a full lifecycle interception pattern (often referred to as an Aspect-Oriented or Decorator pattern):
const _ = require('lodash');
function processOrder(orderId) {
return { orderId, status: 'processed' };
}
const auditedProcessOrder = _.wrap(processOrder, function(originalFn, ...args) {
// Pre-logic
console.time('OrderProcessingTime');
console.log(`Starting processing for: ${args[0]}`);
// Core execution
const result = originalFn(...args);
// Post-logic
console.timeEnd('OrderProcessingTime');
return {
...result,
timestamp: new Date().toISOString()
};
});
auditedProcessOrder('ORD-12345');Common Use Cases
- Instrumentation and Telemetry: Measuring function
execution duration using
console.timeor dedicated Application Performance Monitoring (APM) tools. - Access Control: Verifying user roles or permissions before running sensitive operations.
- Error Handling: Wrapping functions in
try...catchblocks to provide centralized error handling or fallback responses. - Memoization and Caching: Intercepting calls to return cached responses or populating caches after function completion.