AngularJS – extending existing services using decorator

One of the features I miss the most in AngularJS is ability to easy unsubscribe event handlers. There is no convenience function opposed to $on, so in order to unsubscribe event, we have to call method returned by $on function

However in my opinion this approach fails in real life scenarios, because usually we are subscribed to more than one event – thus we have to have multiple local variables for detaching listeners. Fortunately AngularJS provides an easy way to extend existing services with some new functionalities – we can achieve that by using $provide service. This service exposes decorator method, which is able to intercept creation of any service, so we are able to augment it with some new functions. The best moment to call $provide.decorator method is during module configuration, thanks to this approach we are sure that our custom logic is invoked before module is started.

In my case I wanted to extend $rootScope with new method $un for unsubscribing events, so I called method decorator with parameter ‘$rootScope’ (note single quotation marks) – this tells Angular that I will be modifying $rootScope service

Because I passed ‘$rootScope’ as a first argument of $provide.decorator method, the $delegate parameter in extendRootScope function is actually a $rootScope service. Now having access to the service I can augment it with my custom logic for detaching event handlers.

Entire code listing looks then as follows

From now on, you can unsubscribe events handlers simply by calling $un method

and our listener will react only once

AngularJS
Source code for this post can be found here

AngularJS – extending existing services using decorator