0

I'm developing a big app with Angular, and I have the need to launch an event with $rootscope.$emit, and listen to this event inside a factory. I can't do that inside a controller because, when I init the User, the controller hasn't loaded yet.

The code works, but I want to know if this is the best way to do that.

Factory one, which emit the event:

angular
.module('app.core')
.factory('AuthenticationService', ['$rootScope', 'requestHttpService', AuthenticationService])

    function AuthenticationService($rootScope, requestHttpService) {
        var isLoggedIn = false;
        return {
            logIn: logIn
        }
        function logIn(action) {
            return requestHttpService.runOpenRequest(action)
                    .then(logInComplete)
                    .catch(logInError);

            function logInComplete(userData) {
                $rootScope.$emit('initUser', userData);
            }

            function logInError(error) {
                console.log('Something went wrong:  ' + error);
            }
        }
    };

And factory two, which listen to the event:

angular
   .module('app.user')
   .factory('manageUser', ['$rootScope', manageUserFactory]);

    function manageUserFactory($rootScope) {
        var user = {'id': '', 'name': ''};
        $rootScope.$on('initUser', function (event, userData) {
            initUser(userData);
        });

        return {
            initUser: initUser
        }

        function initUser(userData) {
           user = {'id': userData.id, 'name': userData.name};
        }
    };
Tana
  • 108
  • 8
  • Possible duplicate of [Working with $scope.$emit and .$on](http://stackoverflow.com/questions/14502006/working-with-scope-emit-and-on) – Satej S Mar 18 '16 at 09:45
  • I just edit the question because I asked in the case of a factory – Tana Mar 18 '16 at 09:52

1 Answers1

1

I will suggest not to use events here.

As you are using $emit and $emit moves upward in the scope hierarchy including the current scope on which it is emitted and here in your example $rootScope is already at the top. So it will be used only to notify events binded to $rootScope .

I will suggest to call the factory method directly by injecting it as below: replace $rootScope.$emit('initUser', userData); with manageUser.initUser(); by injecting manageUser faactory in AuthenticationService.

Events are least preferred because of their performace cost.

Harpreet
  • 1,527
  • 13
  • 25
  • I undertanding your point, but as I have multiple factories which initializing others modules of my app, I would need to inject too much factories when I manage the init... So I've found that launching a massive event to this factories, I haven't problems with to much injections that difficult code reading. – Tana Mar 18 '16 at 10:20
  • As I already mentioned, events have the cost or they have the performance issues and we must think of this approach if other options not feasible. For dependency injections as you mentioned about readability/maintainability I will suggest to revisit the design to verify if you can merge some factories why you need too much dependency injections at one place, will these all be used etc. – Harpreet Mar 18 '16 at 10:29
  • I take care about this performance issues, but I can't merge any of these factories because they exists on different modules that manage differents parts of the app, which can or can not be actives on the app depending on the server configuration. For example, I could have a module that encapsulates the manage of social sharing in the app, but maybe a client don't want this functionallity active in his application.. So I've developed the app based on functionallity modules that can or can not exits.. – Tana Mar 18 '16 at 10:53
  • My suggestion is to revisit the design of your application to see if any improvements possible for reducing the no. of dependency injections but if you cannot reduce the no. of the dependency injections then the approach you are following with events cannot be considered as the appropriate because the event is emitted at the same scope level and it is always preferable to use events to notify loosely coupled entities which cannot communicate with each other directly or thro' some other component, as you have one common factory through which you can directly call the required method w/o events – Harpreet Mar 18 '16 at 11:51
  • So, which way should I follow? Maybe creating a service to inject all my modules, and then manage the init of the factories inside it? – Tana Mar 18 '16 at 12:06