Why do we use $rootScope.$broadcast in AngularJS?
Solution 1
What does
$rootScope.$broadcast
do?$rootScope.$broadcast
is sending an event through the application scope. Any children scope of that app can catch it using a simple:$scope.$on()
.It is especially useful to send events when you want to reach a scope that is not a direct parent (A branch of a parent for example)
!!! One thing to not do however is to use
$rootScope.$on
from a controller.$rootScope
is the application, when your controller is destroyed that event listener will still exist, and when your controller will be created again, it will just pile up more event listeners. (So one broadcast will be caught multiple times). Use$scope.$on()
instead, and the listeners will also get destroyed.What is the difference between
$rootScope.$broadcast
&$rootScope.$broadcast.apply
?Sometimes you have to use
apply()
, especially when working with directives and other JS libraries. However since I don't know that code base, I wouldn't be able to tell if that's the case here.
Solution 2
$rootScope
basically functions as an event listener and dispatcher.
To answer the question of how it is used, it used in conjunction with rootScope.$on
;
$rootScope.$broadcast("hi");
$rootScope.$on("hi", function(){
//do something
});
However, it is a bad practice to use $rootScope
as your own app's general event service, since you will quickly end up in a situation where every app depends on $rootScope, and you do not know what components are listening to what events.
The best practice is to create a service for each custom event you want to listen to or broadcast.
.service("hiEventService",function($rootScope) {
this.broadcast = function() {$rootScope.$broadcast("hi")}
this.listen = function(callback) {$rootScope.$on("hi",callback)}
})
Solution 3
$rootScope.$broadcast is a convenient way to raise a "global" event which all child scopes can listen for. You only need to use $rootScope
to broadcast the message, since all the descendant scopes can listen for it.
The root scope broadcasts the event:
$rootScope.$broadcast("myEvent");
Any child Scope can listen for the event:
$scope.$on("myEvent",function () {console.log('my event occurred');} );
Why we use $rootScope.$broadcast? You can use $watch
to listen for variable changes and execute functions when the variable state changes. However, in some cases, you simply want to raise an event that other parts of the application can listen for, regardless of any change in scope variable state. This is when $broadcast
is helpful.
Solution 4
Passing data !!!
I wonder why no one mention that $broadcast
accept a parameter where you can pass an Object
Example:
// the object to transfert
var obj = {
status : 10
}
$rootScope.$broadcast('status_updated', obj);
$scope.$on('status_updated', function(event, obj){
console.log(obj.status); // 10
})
Solution 5
What does $rootScope.$broadcast do?
It broadcasts the message to respective listeners all over the angular app, a very powerful means to transfer messages to scopes at different hierarchical level(be it parent , child or siblings)
Similarly, we have $rootScope.$emit, the only difference is the former is also caught by $scope.$on while the latter is caught by only $rootScope.$on .
refer for examples :- http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
Related videos on Youtube
Comments
-
Nexus23 almost 2 years
Tried to find some basic information for AngularJS
$rootScope.$broadcast
, But the AngularJS documentation doesn't help much. In easy words why do we use this?Also, inside John Papa's Hot Towel template there is a custom function in the common module named
$broadcast
:function $broadcast() { return $rootScope.$broadcast.apply($rootScope, arguments); }
I did not understand what this is doing. So here are couple of basic questions:
1) What does
$rootScope.$broadcast
do?2) What is the difference between
$rootScope.$broadcast
and$rootScope.$broadcast.apply
?-
Blackhole almost 10 years
-
Pankaj Parkar almost 10 years
-
Scott Schupbach over 7 years
$rootScope.$broadcast.apply()
is used because if you want to pass the specialarguments
object to another function, you need to useapply()
(as opposed tocall()
). In addition to @Blackhole's link to the MDN page on apply, you might also check out the entry onarguments
.
-
-
Nexus23 almost 10 yearsThanks @itcouldevenbeabout isn't this line calling the same logic of attaching an event to global $rootScope? function() {$rootScope.$broadcast("hi")}, which you mentioned is a bad practice?
-
CoolTapes over 9 yearsUsing a service to make the broadcasts and also attach the listeners for a specific event avoids the situation where you're not sure who is listening. It becomes clear which components have the event service as a dependency
-
tobi about 9 years@itcouldevenbeaboat but if you want to see where it is used you have to search for the service name, but without it you can search for it using just event name? It doesn't give anything more or I overlooked something?
-
Chris Camaratta almost 9 yearsAgreed with the assessment this suggestion appears to be a superficial wrapper. Why is this considered a best practice? Thanks.
-
lawrence almost 9 yearsThis makes refactoring and evolving the code easier. For example, if you wanted to change the event name (e.g. to avoid colliding with some 3rd-party code), or if you wanted to not depend on $rootScope, or if you wanted to add more sophisticated functionality, e.g. keeping track of listeners programmatically, or firing events to only some of them, or waiting for some asynchronous work... then you'd only have to change the service file, not all of its dependents.
-
Brondahl almost 9 yearsHaving just discovered the difference between $emit and $broadcast, I'd be inclined to say that it would be better to $emit the event - that way you the event polluting in the smallest possible set of scopes, (ideally the service would have it's own scope, but I don't think that's possible?)
-
Jadiel de Armas over 8 years@Brondahl, that is a great suggestion, and I second it. It would be better to use $emit in this particular example.
-
alpha-mouse over 8 years-1. I don't see, how isolation in a service is any better than simply broadcasting. Anyway, better use own private scope in the service. And better use $emit, and not $broadcast. Also your proposed service does not support event arguments. What's worse it doesn't support unsubscription; a mortal sin for $rootScope.
-
adamdport over 8 years@alpha-mouse, There is no private
scope
in a service. -
adamdport over 8 yearsThe lack of unsubscription ruins this answer for me. If you call
hiEventService.listen(callback)
from a controller, the listener will still exist even after the controller is destroyed. Memory leak! Binding to controller scope$scope.$on("hi",callback)
comes with automatic cleanup. -
adamdport over 8 yearsGreat catch on the
$rootScope.$on
memory leak. This applies to the accepted answer too, as controllers are likely to call thehiEventService
he created. -
alpha-mouse over 8 years@adamdport one can be created by calling $rootScope.$new. But this doesn't matter much, there are greater problems with the proposed service anyway.
-
Petr Peller almost 8 yearsYour implementation will cause memory leaks as listeners are never unregistered.
-
guest over 7 yearsWhat is an example where you would use
$broadcast
vs.$broadcast.apply()
-
Geert Bellemans about 7 years$rootScope.$broadcast sends the event to all listeners, not only listeners from children scopes. $scope.$broadcast limits the event to child scopes