Search code examples
angularjsangularjs-serviceangularjs-factoryangularjs-events

why a service does not receive events


I have some code that was working in a controller. I refactored and moved that functionality into a service. The code had an event listener:

$rootScope.$on( .....)

This was caught when it was in the controller, but does not catch the event when in a service. I have tried using $rootScope.$broadcast() and $rootScope.$emit() to signal the event but neither are caught in the service.

There is nothing special about the service code:

heartbeatService.$inject = [ '$rootScope', 'vcapChanService', 'eventService', 'logger' ];
function heartbeatService( $rootScope, vcapChanService, eventService, logger ) {
    //....
}

Question: how do I get a service to catch events on the root scope?

Edit with more info: The event is signaled from another service. And this event is caught in other controllers, but is NOT caught in another service. I have tried all variations of service/factory, emit/broadcast, etc. and none of them work. The service just does not catch the event but in all other regards works perfectly.


Solution

  • you can make service bridge between them and use watch

    like

    // bridge service
    angular.module('app').service('bridge', function() {
            var self = this;
            self.events = [];
            self.fireEvent = function(eventName) {
                self.events.push(eventName);
            }
    
            self.removeEvent = function(eventName) {
                var ps = self.events.indexOf(eventName);
                if (ps != -1)
                    self.events.splice(ps, 1) // to remove the event from events array 
            }
        })
        // firstService
    angular.module('app').service('firstService', function($rootScope, bridge) {
            // make your business logic here 
    
            $rootScope.$watchCollection(function() {
                return bridge.events
            }, function(values) {
                var event = 'fileUploaded';
                if (values != null && values.indexOf(event)) {
                    // make what you need to when the event fired
                    // then remove the event from the the service 
                    bridge.removeEvent(event)
                }
            })
    
        })
        // secondService
    angular.module('app').service('secondService', function($rootScope, bridge) {
            var self = this;
            // make your business logic here 
            self.uploadFile = function(file) {
                bridge.fireEvent('fileUploaded');
            }
        })
        // controller
    angular.module('app').controller('Appcontroller', function(secondService, $scope) {
        $scope.clickToUpload = function() {
            secondService.uploadFile( /* file */ );
        }
    
    
    })