OdeToCode IC Logo

Decorating AngularJS Services

Thursday, June 6, 2013

The last post demonstrated a service to wrap geolocation APIs in the browser.

At some point the application might need to add some logging before and after the geolocation calls. One way to do this is to add code to the geo service directly, but AngularJS also allows us to register decorators for any service (including the built-in Angular services).

Decorator is a wonderful pattern for extensibility since the original object doesn’t need to anything about the decoration, and neither does the consumer of the service.

Here is a quick example of creating a decorator for the geo service. The decorator will log the amount of time taken for the geo service to return a result. When creating a decorator, AngularJS will pass the original service as the $delegate parameter.

(function() {
        
    var geoDecorator = function($delegate) {
        var locate = function() {
            var start = new Date();
            var result = $delegate.locate();
            result.always(function () {
                console.log("Geo location took: " + (new Date() - start) + "ms");
            });
            return result;
        };

        return {
          locate: locate  
        };
    };

    var testApp = angular.module("testApp");
    testApp.config(["$provide", function ($provide) {
        $provide.decorator("geo", geoDecorator);
    }]);
    
}());