Chris D
Chris D

Reputation: 225

Lodash flow && get && find together

Consider the following args.roleRateId will be equal to 11604 in this case and args.roleRates will be equal to an array of objects which has multipe values, consider for this exericise the follwing let arr = [ { id:1 , chargeRate: 200} , { id:2 ,chargeRate: 250} ] this will be the values of our args.roleRates. Considering the values above,can someone explain step by step what happens inside

flow(find({ id: args.roleRateId }), get('chargeRate'))(args.roleRates)

I really don't get it

Upvotes: 0

Views: 901

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

In lodash/fp all functions have a fixed arity. Arity is the number of arguments that a function can accept. Fixed arity means that the number is not dynamic.

Functions with fixed arity can be curried - ie whenever the function is invoked with a number of arguments which is less than the arity of the function, the function is not invoked, but returns a new function with an arity equals to original arity - number of arguments. Whenever the number of arguments is equal to the original arity, the function is invoked, and returns the result.

  • find is a function with arity of 2, when you call find({ id: args.roleRateId }), a new function with arity of 1 is returned. When that function is called with a single argument (an array), find will return an actual result (the found item).

  • get is a function with arity of 2, when you call get('chargeRate'), a new function with arity of 1 is returned. When that function is called with a single argument, get will return the actual result (the value of the property).

The flow function, receives one or more functions (flow's arity is not fixed), and returns a new function (let's call it fn). Whatever fn receives is passed to the 1st function it was created with (find in your case). The result of that function is passed to the 2nd function (get in your case), and so on (if there are more than 2). The return value of the last function (the get) is the result of fn.

Since your case you get a single args object, you need to manually split it, and assign it the outer flow function, and the internal find function:

const { flow, find, get } = _

const fn = args => flow(
  find({ id: args.roleRateId }),
  get('chargeRate')
)(args.roleRates)

const args = {
  roleRateId: 1,
  roleRates: [{ id:1 , chargeRate: 200 }, { id:2 ,chargeRate: 250 }]
}

const result = fn(args)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

You can also create a function using flow that extracts the properties from args, without the need to pass them manually:

const { flow, props, spread, useWith, find, identity, get } = _

const fn = flow(
  props(['roleRateId', 'roleRates']), // get an array of [roldRateId, roleRates]
  spread(useWith(find, [id => ({ id }), identity])), // create a function that takes the props array, convert the roleRateId value to { id: value } object, invokes find
  get('chargeRate') // get the chargeRate's value from the result of find
)

const args = {
  roleRateId: 1,
  roleRates: [{ id:1 , chargeRate: 200 }, { id:2 ,chargeRate: 250 }]
}

const result = fn(args)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

Upvotes: 2

Related Questions