201

I was looking how filters works in Angularjs and I saw that we need to send 2 sets of parentheses.

$filter('number')(number[, fractionSize])

What does it means and how do we handle it with JavaScript?

M. Abbas
  • 6,409
  • 4
  • 33
  • 46
L105
  • 5,379
  • 3
  • 18
  • 23
  • 8
    Personally I find this syntax confusing / awkward to read as well. But you can use simpler syntax to access AngularJS filters as described here: http://stackoverflow.com/a/14303362/1418796 – pkozlowski.opensource Aug 14 '13 at 14:41
  • I took angularjs as an exemple. I wanted to know how to handle this if I create a function myself. – L105 Aug 14 '13 at 14:45
  • 7
    Actually it's called "currying". a programming technique. – Sajuuk Jul 26 '18 at 11:52

4 Answers4

398

It means that the first function ($filter) returns another function and then that returned function is called immediately. For Example:

function add(x){
  return function(y){
    return x + y;
  };
}

var addTwo = add(2);

addTwo(4) === 6; // true
add(3)(4) === 7; // true
Paul
  • 139,544
  • 27
  • 275
  • 264
  • 26
    With ES6 arrow functions you could write it the following way: `let add = (x) => (y) => x + y;` – guido Nov 19 '15 at 08:14
  • 4
    Call me a Noob, but please spare your time to explain how can sub-function is able to hold the value of `x` – Vikas Bansal Mar 27 '16 at 17:38
  • 3
    @VikasBansal Every time a function is called in Javascript a new execution context is created, as long as there is a reference to another function inside it that execution context will stay in memory. – Paul Mar 29 '16 at 17:17
  • if I use `this` to access the variables `x and y` then will it be alright? e.g. `return this.x + this.y` @Paulpro – Vikas Bansal Mar 29 '16 at 17:39
  • @VikasBansal No, only global variables are automatically considered to be properties of an object. `this` always refers to an object, but there is no object that `x` is a property of. – Paul Mar 29 '16 at 18:21
  • 20
    Why not just pass 2 arguments like `add(x, y)` ? Where is the benefit of calling it like so? – Piotr Pawlik Aug 22 '17 at 08:01
  • 2
    Thanks for this explanation! Really helped me to understand how passportjs authentication works: `passport.authenticate("local")(req, res, function(){` – tidydee Nov 16 '17 at 17:34
  • I was thinking the same thing, why would I use this ? Real world example anyone? – Kanga Feb 09 '18 at 01:08
  • Well, the real world example is in OP's question. The $filter service in AngularJS. Here's another example: $scope.lowercasehandle = function(){ return $filter('lowercase')($scope.handle); } The second argument will be converted to all lowercase. – Futureproof Aug 09 '18 at 15:33
  • A "closure" function as it is now known to be. – hadifikri Feb 28 '20 at 18:22
28

$filter('number') returns a function that accepts two arguments, the first being required (a number) and the second one being optional (the fraction size).

It's possible to immediately call the returned function:

$filter('number')('123')

Alternatively, you may keep the returned function for future use:

var numberFilter = $filter('number');

numberFilter('123')
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • this; looks complex: export const toursListQuery = gql` query ToursListQuery { tours { id name } } `; export default graphql(toursListQuery, { options: { pollInterval: 10000 }, })(ToursList); – stackdave Oct 18 '17 at 22:41
7

It is the same as this:

var func = $filter('number');
func(number[, fractionSize]);

The $filter() function returns a pointer to another function.

Paul
  • 139,544
  • 27
  • 275
  • 264
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
2

with ES6 or later versions you can do it that way;

const divideBoth = (x) => (y) => {
   return x / y;
};

one of the reasons that makes this function type useful is when you have a react.js component that needs have callback function instead of doing it inline way(which is ()=>return value) you can do it the way we did previously. But it is not recommended to use in event callbacks because it gets execute in the first render which might cause issues sometimes

Ömer Ayhan
  • 73
  • 1
  • 4