Search code examples
javascriptangularjsdesign-patternspublish-subscribe

Pub/Sub design pattern angularjs service


I've been trying to use the answer here posted by Mark Rajcok

angular JS - communicate between non-dependend services

I am having trouble understanding his answer. Specially this part:

angular.forEach(event1ServiceHandlers, function(handler) {
            handler(some_data);
});

Is the event1ServiceHandlers array populated with functions (here called handler) that is triggered in this forEach loop?

I think it would be much easier to understand with a good example how a publish/subscribe is set up.

I have two services who need to communicate but I want to avoid $rootScope.$broadcast so from what I have read a pub/sub service is the best approach. One of my services need to execute a function on my other service, but that service already has my first service as a dependency so I cannot do the same both ways because of circular dependency.

My question: So assume you have two angularjs services (factory), how does service 1 execute a function on service 2 if service 2 already has service 1 as a dependency. Not using $broadcast and $on


Solution

  • Is the event1ServiceHandlers array populated with functions (here called handler) that is triggered in this forEach loop?

    Yes

    how does service 1 execute a function on service 2 if service 2 already has service 1 as a dependency

    Create service 3, NotificationService as before:

    .factory('NotificationService', [function() {
        var event1ServiceHandlers = [];
        return {
            // publish
            event1Happened: function(some_data) {
                angular.forEach(event1ServiceHandlers, function(handler) {
                    handler(some_data);
                });
            },
            // subscribe
            onEvent1: function(handler) {
                event1ServiceHandlers.push(handler);
            }
        };
    }])
    

    Have service 2 register a callback function with the NotificationService:

    .factory('Service2', ['NotificationService',
    function(NotificationService) {
        // event1 handler
        var doSomething = function(someData) {
            console.log('S2', someData);
            // do something here
        }
        // subscribe to event1
        NotificationService.onEvent1(doSomething);
        return {
          // define public API for Service2 here
        }
    }])
    

    Whenever service 1 wants function doSomething() on service 2 to execute, it can publish the event1Happened event:

    .factory('Service1', ['NotificationService',
    function(NotificationService) {
        var someData = ...;
        return {
           // define public API for Service1 here
           callService2Method: function() {
             // publish event
             NotificationService.event1Happened(someData);
           }
        }
    }])