Why can't I chain this series of lodash calls?

coffeescript, javascript, lodash, underscore.js

Solution

Here's the generated JavaScript with better indentation:

_(gameState.loot).pick(function(value, key) {
    return key !== "pickUpAnimations";
}).filter(
    (function(d) {
        return _.isArray(d);
    }).reduce((function(sum, d) {
        return sum.concat(d);
    }))
);

As you can see, `.filter (...` and `.filter(...` are not the same. Two possible fixes:

Remove the whitespace between the method names and the opening parentheses:

_(gameState.loot)
    .pick((value, key) -> key isnt "pickUpAnimations")
    .filter((d) -> _.isArray (d))
    .reduce((sum, d) -> sum.concat (d))

Remove the parentheses entirely:

_(gameState.loot)
    .pick (value, key) -> key isnt "pickUpAnimations"
    .filter (d) -> _.isArray (d)
    .reduce (sum, d) -> sum.concat (d)

You can also get rid of the anonymous function calling `_.isArray`:

    _(gameState.loot)
        .pick (value, key) -> key isnt "pickUpAnimations"
        .filter _.isArray
        .reduce (sum, d) -> sum.concat (d)

Problem

This code: ``` _(gameState.loot) .pick((value, key) -> key isnt "pickUpAnimations") .filter ((d) -> _.isArray (d)) .reduce ((sum, d) -> sum.concat (d)) ``` Is giving me this error: ``` TypeError: 'undefined' is not a function (evaluating '(function(d) { ``` Whereas this code works fine: ``` removedAnimations = _.pick(gameState.loot, (value, key) -> key isnt "pickUpAnimations") removedAnimations = _.filter removedAnimations, ((d) -> _.isArray (d)) removedAnimations = _.reduce removedAnimations, ((sum, d) -> sum.concat (d)) removedAnimations ``` To me it seems that these should be doing the same thing. The schema of `gameState.loot` looks like this: ``` loot: { ttl: 6000 slowBlinkWhenTtlLessThanPercent: 60 fastBlinkWhenTtlLessThanPercent: 30 resurrections: [] gold: [] health: [] equipment: [] pickUpAnimations: [] } ``` BTW, this is the javascript being generated from the first example: ``` return _(gameState.loot).pick(function(value, key) { return key !== "pickUpAnimations"; }).filter((function(d) { return _.isArray(d); }).reduce((function(sum, d) { return sum.concat(d); }))); ``` I tried @Blender's suggestion of this: ``` _(gameState.loot) .pick (value, key) -> key isnt "pickUpAnimations" .filter (d) -> _.isArray (d) .reduce (sum, d) -> sum.concat (d) ``` But that gave me this error: ``` >> TypeError: 'undefined' is not a function (evaluating '"pickUpAnimations".filter(function(d) { ``` Here's how the javascript looks like: ``` return _(gameState.loot).pick(function(value, key) { return key !== "pickUpAnimations".filter(function(d) { return _.isArray(d.reduce(function(sum, d) { return sum.concat(d); })); }); }); ```

Original source