20

It sends $broadcast once from the rootScope, but the listener ($on) gets called twice.

The listener is in a controller and it uses $rootScope.$on instead of $scope.$on. Has someone had this problem?

edit

rootScope:

$rootScope.$broadcast('menuActivateAction' + item.event_name_postfix, item.event_args);

other Controller:

$rootScope.$on('menuActivateActionPublish', function(event) {});
Shai M.
  • 1,284
  • 4
  • 17
  • 30
  • 2
    you should provide your code – Grundy Jun 21 '15 at 20:25
  • 2
    Maybe you have two controllers? – kaaposc Jun 21 '15 at 20:28
  • 1
    Probably you have to remove the listener when the controller is destroyed. I'd even register the listener in the `.run` phase and not in the controller - to avoid auch problems the controller should only register listener on is own scope – Michael Jun 21 '15 at 20:42
  • Possible duplicate of [AngularJs broadcast repeating execution too many times](http://stackoverflow.com/questions/19553598/angularjs-broadcast-repeating-execution-too-many-times) – kinkajou Jan 18 '17 at 01:29

4 Answers4

31

Since you register your $on listener on $rootScope, it doesn't get destroyed with the controller and next time you init the controller it gets created again.

You should create your listener on controller scope

$scope.$on('menuActivateActionPublish', function(event) {});
Tomas
  • 2,676
  • 5
  • 41
  • 51
  • Hey in my case on listen called incrementally. – Umair Ahmed Feb 19 '16 at 11:41
  • 1
    @UmairKhanzada sorry I dont understand that comment – Tomas Feb 19 '16 at 14:15
  • listen `$rootScope.$broadcast('xyz');` event when user login and when user logout and login again it'll be listen incrementally. listen function `$rootScope.$on('xyz', function(){ console.log('running')});` – Umair Ahmed Feb 20 '16 at 06:13
  • It depends on where do you have `$broadcast` and `$on` . In your case, you should have `$broadcast()` in function that handles login - wherever you determine that user is logged in, and `$on()` only in single place. For example `app.run()`. That is if you want to use `$rootScope`. If you want to use it in controllers or other "modules" then use `$scope.$on()` and as many times you want, because it gets destroyed – Tomas Feb 20 '16 at 17:34
10

Be careful you avoid two instances of the controller means two event listeners, which means the method gets executed twice !! ( example: using twice 'ng-controller' )

que1326
  • 2,227
  • 4
  • 41
  • 58
4

To complement que1326 answer, as an example, if you are using ui-router and have something like

.state('app.yourpage', {
            url:'yourPage',
            views: {
                'content@': {
                    templateUrl : 'views/yourPage.html',
                    controller  : 'YourController'
                }
            }
        })

and in yourPage.html you have a ng-controller="YourController as Ctrl", then you are creating 2 instances of the controller: 1 instance is created by the state configuration and another one in your html.

João Otero
  • 948
  • 1
  • 15
  • 30
0

The only solution I could get to work was to create the listener inside the $viewContentLoaded event:

$scope.$on('$viewContentLoaded', function() {
  //Put your listener(s) in here
  $scope.$on('menuActivateActionPublish', function(event) {});
});
Big Sam
  • 1,290
  • 14
  • 7