AngularJs broadcast repeating execution too many times

AngularjsAngularjs Scope

Angularjs Problem Overview


Inside one of my Angular controllers, I have this:

// controller A
$rootScope.$on("myEventFire", function(event, reload) {
	someAction();
});

In another controller I have this:

// controller B
$scope.openList = function(page) {
	$rootScope.$broadcast('myEventFire', 1);
}

Now, this is a single-page app. When I go to controller A initially and try triggering this event, someAction() is going to be executed once. If I navigate away and come back again to controller A and do the same thing, someAction() gets executed twice. If I do it again, it happens three times and so on. What am I doing wrong here?

Angularjs Solutions


Solution 1 - Angularjs

Can you try just using $scope.$on()? Every time controller A is created, it is adding a new listener on the root scope, and that doesn't get destroyed when you navigate away and back. If you do it on the controller's local scope, the listener should get removed when you navigate away and your scope gets destroyed.

// controller A
$scope.$on("myEventFire", function(event, reload) {
    someAction();
});

$broadcast sends the event downward to all child scopes so it should be picked up on your local scope. $emit works the other way bubbling up towards the root scope.

Solution 2 - Angularjs

you can also remove it when the scope is destroyed, by running the return callback from the $rootScope.$on().

I.e.

var destroyFoo;

destroyFoo = $rootScope.$on('foo', function() {});

$scope.$on('$destroy', function() {
  destroyFoo(); // remove listener.
});       

Solution 3 - Angularjs

if you don't want to destroy,

I think we can check the listener event first - AngularJS 1.2.15

Check listener event - example

So I think this should work :

if(!$rootScope.$$listenerCount['myEventFire']){
	$rootScope.$on("myEventFire", function(event, reload) {
		someAction();
	});
}

Solution 4 - Angularjs

If it helps anyone I had a similar issue in a directive. Each time the directive opened the number of times the event was fired increased.

I solved it by using the following (this was in my controllers init function but I guess it could have been defined in the controller itself. In my case my controller needed to reinitialise when the event fired)

 if (!$scope.onMyEvent) $scope.onMyEvent= $scope.$on('myEvent',function(event,data){
        .....
        });

Solution 5 - Angularjs

For my case...

if ($rootScope.$$listenerCount['myEventFire']) {
    $rootScope.$$listeners.broadcastShowMessageError = [];
};

$rootScope.$on('myEventFire', function (event, reload) {
    someAction();
})

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmisaizdalekaView Question on Stackoverflow
Solution 1 - AngularjsJason GoemaatView Answer on Stackoverflow
Solution 2 - Angularjsjaf0View Answer on Stackoverflow
Solution 3 - Angularjsvanduc1102View Answer on Stackoverflow
Solution 4 - AngularjsRichard TurnerView Answer on Stackoverflow
Solution 5 - AngularjsArthur MenezesView Answer on Stackoverflow