Why do we use $rootScope.$broadcast in AngularJS?
Asked Answered
S

5

116

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?

Spelldown answered 18/7, 2014 at 17:29 Comment(3)
developer.mozilla.org/en-US/docs/JavaScript/Reference/…Forsworn
mariuszprzydatek.com/2013/12/28/…Ecclesiastical
$rootScope.$broadcast.apply() is used because if you want to pass the special arguments object to another function, you need to use apply() (as opposed to call()). In addition to @Blackhole's link to the MDN page on apply, you might also check out the entry on arguments.Maidel
V
107
  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.

  2. 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.

Villagomez answered 17/4, 2015 at 4:16 Comment(3)
Great catch on the $rootScope.$on memory leak. This applies to the accepted answer too, as controllers are likely to call the hiEventService he created.Aloud
What is an example where you would use $broadcast vs. $broadcast.apply()Leede
$rootScope.$broadcast sends the event to all listeners, not only listeners from children scopes. $scope.$broadcast limits the event to child scopesBrent
S
159

$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)}
})
Scarborough answered 18/7, 2014 at 18:58 Comment(12)
Thanks @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?Spelldown
Using 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 dependencyStringed
@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?Monika
Agreed with the assessment this suggestion appears to be a superficial wrapper. Why is this considered a best practice? Thanks.Derrickderriey
This 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.Roethke
Having 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?)Maleficence
@Brondahl, that is a great suggestion, and I second it. It would be better to use $emit in this particular example.Cnidus
-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.Irrecoverable
@alpha-mouse, There is no private scope in a service.Aloud
The 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.Aloud
@Aloud one can be created by calling $rootScope.$new. But this doesn't matter much, there are greater problems with the proposed service anyway.Irrecoverable
Your implementation will cause memory leaks as listeners are never unregistered.Catamenia
V
107
  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.

  2. 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.

Villagomez answered 17/4, 2015 at 4:16 Comment(3)
Great catch on the $rootScope.$on memory leak. This applies to the accepted answer too, as controllers are likely to call the hiEventService he created.Aloud
What is an example where you would use $broadcast vs. $broadcast.apply()Leede
$rootScope.$broadcast sends the event to all listeners, not only listeners from children scopes. $scope.$broadcast limits the event to child scopesBrent
B
33

$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.

Baskin answered 22/12, 2014 at 20:2 Comment(0)
D
25

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
})
Disunion answered 8/11, 2016 at 12:10 Comment(0)
E
8

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/

Eadie answered 5/11, 2014 at 10:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.