Erazihel
Erazihel

Reputation: 7605

Pass $rootScope parameter to named function in factory

I'm working on an application that is very moduralized. In this app, I've got a factory whose work is to send notifications to a controller from another module. To achieve this, I'm using the $rootScope object to trigger an event called newNotification and pass the data.

Everything works fine using the code below:

notifications.factory.js

(function() {
    'use strict';

    function notificationsFactory($rootScope) {
        return {
            sendNotification: function(data) {
                switch(data.type) {
                    case 'actors':
                        $rootScope.$broadcast('newNotification', data);
                        break;
                    .....
                }
            } 
        }
    };

    angular.module('features.notifications.factory', [])
    .factory('notificationsFactory', ['$rootScope', notificationsFactory]);
})();

So, what's the problem ? Well, the thing is, to get a more clean factory, since more functions will be added, the purpose is to return an object with named function.

To be a bit more clear, what I'm aiming at is something that will look like this:

notifications.factory.js

(function() {
    'use strict';

    function notificationsFactory($rootScope) {
        return {
            sendNotification: sendNotification
        }
    };

    function sendNotification(data) {
        switch(data.type) {
            case 'actors':
                $rootScope.$broadcast('newNotification', data);
                break;
            ....
        }
    };

    angular.module('features.notifications.factory', [])
    .factory('notificationsFactory', ['$rootScope', notificationsFactory]);
})();

In this case, the problem is that the $rootScope object is not defined in the sendNotification function, which is obvious. But I can't figure out how to solve this.

I've looked for solution on internet, thing is, the problem is really hard to be expressed clearly without putting some code, thus my post.

Thanks for your consideration :)

Upvotes: 1

Views: 1096

Answers (2)

Ori Drori
Ori Drori

Reputation: 191976

If you use a service instead of a factory, you can transfer the injected dependencies using this. Using a service in this way is even nicer, when you use ES6 classes, and makes you slightly more Angular 2.0 ready.

(function() {
    'use strict';

    function NotificationsService($rootScope) {
        this.$rootScope = $rootScope;
    };

    NotificationsService.prototype.sendNotification = function sendNotification(data) {
        switch(data.type) {
            case 'actors':
                this.$rootScope.$broadcast('newNotification', data);
                break;
            ....
        }
    };

    angular.module('features.notifications.service', [])
    .service('NotificationsService', ['$rootScope', NotificationsService]);
})();

ES6 Version:

(function() {
    'use strict';

    class NotificationsService {
        constructor($rootScope) {
            this.$rootScope = $rootScope;
        }

        sendNotification(data) {
            switch(data.type) {
                case 'actors':
                    this.$rootScope.$broadcast('newNotification', data);
                    break;
                ....
            }
        }
    }

    angular.module('features.notifications.service', [])
    .service('NotificationsService', ['$rootScope', NotificationsService]);
})();

Upvotes: 3

Gustav
Gustav

Reputation: 3576

Declare the sendNotification-function inside your notificationsFactory- factory function:

function notificationsFactory($rootScope) {
    function sendNotification(data) {
        switch(data.type) {
            case 'actors':
                $rootScope.$broadcast('newNotification', data);
                break;
            ....
        }
      };
      return {
          sendNotification: sendNotification
      }
    };

or use service instead of factory and you can write something like this:

function notificationsFactory($rootScope) {
    this.sendNotification = function(data) {
        switch(data.type) {
            case 'actors':
                $rootScope.$broadcast('newNotification', data);
                break;
            ....
        }
      };
    };

Upvotes: 1

Related Questions