Lodash flow中调用get报错Expected a function,求解决方法
Let's break this down clearly—you ran into a classic gotcha with Lodash's currying and how flow works.
The Root Cause of the Error
First, remember what flow does: it chains together functions, where each function takes the output of the previous one as its input. Every argument you pass to flow must be a function—not a pre-computed value.
Here's what went wrong when you modified your code:
- Your original code used
get('chargeRate')which works because Lodash automatically curries many of its functions. When you callgetwith only the path, it returns a new function that waits for an object to query. That's whyflowcould use it—it's a valid function step. - When you changed it to
get('chargeRate', args.roleRate), you're callinggetimmediately with two arguments. Lodash'sgetsignature is_.get(object, path, defaultValue), so right now you're telling it to:- Treat the string
'chargeRate'as the object to search - Use
args.roleRateas the path to look up - Since there's no valid object here, it returns
undefined(or irrelevant data)
- Treat the string
- Worse, this call returns a value, not a function. When
flowtries to execute this value as the next step in the chain, it throws "Expected a function" because it can't run a non-function.
Two Simple Fixes
You have two solid options to fix this, depending on which style you prefer:
Option 1: Use _.partial to Curry the get Call
_.partial lets you pre-fill some arguments of a function and return a new function that accepts the remaining ones. This is perfect for keeping things Lodash-native:
flow( find({ id: args.roleRateId }), partial(get, 'chargeRate', args.roleRate) // Returns a function waiting for the object )(args.roleRates)
This creates a new function that will take the result from find (your matched role rate object) and run get(matchedObject, 'chargeRate', args.roleRate)—exactly what you intended.
Option 2: Use an Arrow Function (More Explicit)
If you want to avoid remembering Lodash's currying rules, wrap the get call in an arrow function. This makes the logic crystal clear:
flow( find({ id: args.roleRateId }), (foundRoleRate) => get(foundRoleRate, 'chargeRate', args.roleRate) )(args.roleRates)
The arrow function takes the object found by find (or undefined if nothing was found) and passes it as the first argument to get, along with your path and default value. No currying magic needed—just plain, readable code.
Quick Summary
- The error happens because
get('chargeRate', args.roleRate)runs immediately and returns a value, not a function thatflowcan use in its chain. - Fix it by either currying
getwithpartialor wrapping it in an arrow function to keep it as a valid step in the flow.
内容的提问来源于stack exchange,提问作者Chris D

