Pete Pete - 7 months ago 60
Javascript Question

How does the _.invoke method work in Lodash?

Background



From the documentation about the invoke method, I read:


Invokes the method named by methodName on each element in collection, returning an array of the results of each invoked method


Thus, I assumed that the following code would be synonymous, but this is not the case:

_.map(items, function(item) {
return _.omit(item, 'fieldName');
})

_.invoke(items, _.omit, 'fieldName');


In this case, the
invoke
method produces an array of strings, while the map method returns an array of items with
fieldName
removed from each item.

Questions




  • How can one use the
    invoke
    method to achieve the same result as the
    map
    function?

  • Why did
    invoke
    return the array of strings in this particular situation?





var items = [{id:1, name:'foo'},
{id:2, name:'bar'},
{id:3, name:'baz'},
{id:4, name:'qux'}];

console.log(
_.invoke(items, _.omit, 'id')
);

console.log(
_.map(items, function(item) {
return _.omit(item, 'id');
})
);

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.min.js"></script>




Answer
var result = _.invoke(items, fn, extraArgs)

Is equivalent to

var result = [];
for (var i=0; i<items.length; i++) {
  result.push( fn.apply(items[i], extraArgs) );
}

So if you want the same result as your map, it would be

_.invoke(items, function() {
  return _.omit(this, 'id');
})

The only difference is that item is not a parameter of the function, instead you need to use this as the function is applied to the item.

Comments