13

I have the following set up:

stApp.controller('AdminTableController', ['$rootScope', '$scope', 'gridService', 
            function ($rootScope, $scope, gridService) {
    $scope.$watch('tableData.$pristine', function (newValue) {
        $rootScope.broadcast("tableDataUpdated", {
            state: page.$pristine
        });
    });
}])

stApp.controller('AdminGridController', ['$rootScope', '$scope', 'gridService',
            function ($rootScope, $scope, gridService) {
    $rootScope.on("tableDataUpdated", function (args) {
        //args.state would have the state.
        alert(args.state);
    });
}])

When I run this code I am getting a message:

Object #<Object> has no method 'on'

Note that I tried this with both $rootScope.on and $scope.on

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100

4 Answers4

21

You must have meant $broadcast and $on (rather than broadcast and on), that is:

$rootScope.$broadcast("tableDataUpdated", { state: page.$pristine });
// ...
$rootScope.$on("tableDataUpdated", function (args) {
// ...

It's worth noting that $broadcast is used to delegate events to child or sibling scopes, whereas $emit will bubble events upwards to the scope's parents, hence;

When choosing $broadcast (and not $emit), one should either inject the root scope for tying the $on (as you nicely did) or call $on on the receiver's isolated scope, be it a child scope of the dispatcher.

See this post for elaboration on $emit and $broadcast.

Community
  • 1
  • 1
Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
7

If the event listener is in a child scope: $scope.$broadcast('MyEvent', args);

If the event listener is in a parent scope: $scope.$emit('MyEvent', args);

You could avoid any confusion by using $broadcast on $rootScope, since $rootScope is the parent of all scopes in an Angular application: $rootScope.$broadcast('MyEvent', args);

Whether you use $emit or $broadcast, the receiving controller listens with $scope.$on('MyEvent', function() {});

Jake McGuire
  • 304
  • 2
  • 4
  • 1
    I think it is the other way around. $emit sends upwards from child scope to parent scope. $broadcast goes from parent to child. See https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit – Peter Drinnan Jul 30 '14 at 15:05
  • 1
    You're absolutely right -- I wrote listener instead of emitter, but I've fixed it here so they're reversed. Thanks! – Jake McGuire Aug 01 '14 at 16:15
2
 $rootScope.on("tableDataUpdated", function (args) {
        //args.state would have the state.
        alert(args.state);
    });

should be

 $rootScope.$on("tableDataUpdated", function (args) {
        //args.state would have the state.
        alert(args.state);
    });
rajasaur
  • 5,340
  • 2
  • 27
  • 22
0
$scope.$emit('MyEvent', args);

from first controller, and receive in second controller:

$scope.$on('MyEvent', function() {});
0xAX
  • 20,957
  • 26
  • 117
  • 206