Slava
Slava

Reputation: 6640

Can someone explain the meaning of writing code like this?

I saw original angularjs code and there are many functions defined like this

this.$get = function() {
    return function ngParamSerializer(params) {
        // some content...
    };
}

I have no idea what for... and why is it needed. a function that return a function? will it not return the result of the inner function?

Why not just write?

this.$get = function() {
    // some content...
}

Example:

this.$get = function() {
    return function ngParamSerializer(params) {
         return "Hello World"
    };
}

Isn't it the same as

this.$get = function() {
    return "Hello World"
}

Will you not get "Hello World" when you call the this.$get() ??

Upvotes: 1

Views: 105

Answers (3)

Dániel Kis-Nagy
Dániel Kis-Nagy

Reputation: 2495

By the looks of it, you probably saw this in the code of a Provider.

They mostly look like this:

app.config(function ($provide) {
    $provide.provider('globalsetting', function () {
        this.$get = function () {
            var appname = "Lawyer App";
            return {
                appName: appname
            };
        }
    })
});

which then can be used like this:

app.controller("ProductController", function ($scope, globalsetting) {
    $scope.name = globalsetting.appName;
});

(example borrowed from the Infragistics blog)

Now imagine that this code is a bit more complex, and you want your service to be reusable, but to vary slightly between applications. Like this:

app.config(function ($provide) {
    $provide.provider('globalsetting', function () {
        this.$get = function (appAudience) {
            var appname = appAudience + " App";
            return {
                appName: appname
            };
        }
    })
});

But as you can see in the usage example, $get will be called by the framework, not you, so you can't directly pass parameters to it. So one thing you can do is to return a function (which can have parameters, unlike $get), not a fixed value:

app.config(function ($provide) {
    $provide.provider('globalsetting', function () {
        this.$get = function () {
            return {
                getAppName: function (appAudience) {
                    return appAudience + " App";
                }
            };
        }
    })
});

And then use it like this:

app.controller("ProductController", function ($scope, globalsetting) {
    $scope.name = globalsetting.getAppName("Lawyer");
    //$scope.name is now "Lawyer App"
});

Seeing that your example code returns a function with params, I'd guess this is the reason in your case too. Note that, however, there are more sophisticated ways for doing this.

Upvotes: 1

alexmac
alexmac

Reputation: 19587

It could be helpful when the inner function is called not by you, but you want to provide some parameters into this function.

I don't know how $get function from your example is used by angular, so I'll provide an example from node.js express module. There is the concept of middleware. Middleware is a function which accepts three parameters req, res, next and calls next function with/without error parameter to stop/continue processing. Middlewares are called by express in the order of declaration.

In the example below, I want to define a route and add authentication logic to restrict access to the resource. As you see auth accepts userRole parameter, and uses it when middleware is called by express:

app.get('/user/:id', auth('admin'), getUser);

let auth = function(userRole) {
  return function(req, res, next) {
    if (userRole === 'admin') {
      return next();
    }
    return next(new Error('Auth error'));
  };
}

Upvotes: 1

stefan bachert
stefan bachert

Reputation: 9608

In javascript functions are real citizens. You could assign functions to vars.

var f = function (a, b) {
    return a + b;
}

var f2 = f;

console.log (f(1,2)); // -> 3
console.log (f2(4,5)); // -> 9

The sense of the first example is to return a function which will be called by the caller. this is a kind of callback

In your case, you can ask $get for a function which you can call later with your parameters

  var n = this.$get();
  for (var i = 0; i < 1000; i ++) {
     ...
     n(i, i*i);   // call function, e.g. notify others.
     ...
  }

returning directly the result of n is obviously not the same because this would not allow to pass parameters.

Upvotes: 1

Related Questions