In Focus

Communication Among Controllers in AngularJS

This article explains various ways to communicate among controllers in AngularJS.

AngularJs provides the $broadcast, $on and  $emit services for event-based communication among controllers. This is very similar to the publisher subscriber pattern.

We can use root scope or service to pass data across controllers:

  • $broadcast: dispatches the event downwards to all child scopes.
  • $emit: dispatches the event upwards using the scope hierarchy.
  • $on: listen on the events of a given type. It can catch the event dispatched by $broadcast and $emit.

We will do a sample to understand how to communicate among controllers.

Using $broadcast

We will see three controllers named ControllerBase, ControllerOne and ControllerTwo. From the ControllerBase we will pass some values to ControllerOne and ControllerTwo.

  1. <html ng-app="myModule">  
  2. <head>  
  3.     <title>AngularJS Communicating across controllers</title>  
  4.     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>  
  5.     <script>  
  6.         var myModule = angular.module('myModule', []);  
  7.         myModule.factory('commonDataService'function ($rootScope) {  
  8.             var dataService = myModule  
  9.   
  10.             dataService.message = '';  
  11.   
  12.             dataService.prepForBroadcast = function (msg) {  
  13.                 this.message = msg;  
  14.                 this.broadcastItem();  
  15.             };  
  16.   
  17.             dataService.broadcastItem = function () {  
  18.                 $rootScope.$broadcast('broadCastData');  
  19.             };  
  20.   
  21.             return dataService;  
  22.         });  
  23.   
  24.         function ControllerBase($scope, dataService) {  
  25.             $scope.handleClick = function (msg) {  
  26.                 dataService.prepForBroadcast(msg);  
  27.             };  
  28.   
  29.             $scope.$on('broadCastData'function () {  
  30.                 $scope.message = dataService.message;  
  31.             });  
  32.         }  
  33.   
  34.         function ControllerOne($scope, dataService) {  
  35.             $scope.$on('broadCastData'function () {  
  36.                 $scope.message = 'In ControllerOne ,Value is : ' + dataService.message;  
  37.             });  
  38.         }  
  39.   
  40.         function ControllerTwo($scope, dataService) {  
  41.             $scope.$on('broadCastData'function () {  
  42.                 $scope.message = 'In ControllerTwo,Value is :' + dataService.message;  
  43.             });  
  44.         }  
  45.   
  46.         ControllerBase.$inject = ['$scope''commonDataService'];  
  47.   
  48.         ControllerOne.$inject = ['$scope''commonDataService'];  
  49.   
  50.         ControllerTwo.$inject = ['$scope''commonDataService'];  
  51.     </script>  
  52. </head>  
  53. <body>  
  54.   
  55.     <div style="border: 5px solid gray; width: 500px;">  
  56.         <p> This is ControllerBase</p>  
  57.         <div ng-controller="ControllerBase">  
  58.             <input ng-model="message"   style="width:300px;">  
  59.             <button ng-click="handleClick(message);">Pass From First Controller  
  60.   
  61.             </button>  
  62.         </div>  
  63.   
  64.          <p> This is ControllerOne</p>  
  65.         <div ng-controller="ControllerOne">  
  66.             <input ng-model="message"  style="width:300px;">  
  67.         </div>  
  68.              <p> This is ControllerTwo</p>  
  69.         <div ng-controller="ControllerTwo">  
  70.             <input ng-model="message"  style="width:300px;">  
  71.         </div>  
  72.         <br />  
  73.     </div>  
  74. </body>  
  75. </html>  

Here the event life cycle starts at the scope on which $broadcast was called (here the ControllerBase). All listeners listening for the name event on this scope are notified (ControllerOne and ControllerTwo.).

Here in the BaseController we call Broadcast Message that assigns scope data from the factory as in the following code snippet:

  1.  dataService.broadcastItem = function () {  
  2.   
  3.    $rootScope.$broadcast('broadCastData');  
  4.   
  5. }; 

And in ControllerOne we get the value by $on as in the following code snippet:

  1. $scope.$on('broadCastData', function () {  
  2.   
  3. scope.message = 'In ControllerOne ,Value is : ' + dataService.message; 

Using $Rootscope

Using rootscope we can set the value in one controller and read it from other controller.

The following is the sample code snippet: 

 
  1. <!DOCTYPE html>  
  2. <html ng-app="myApp">  
  3. <head>  
  4.     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js">  
  5.     </script>  
  6.     <script>  
  7.         var myApp = angular.module('myApp', []);  
  8.         function controllerOne($scope, $rootScope) {  
  9.             $rootScope.name = 'From Rootscope set in controllerOne';  
  10.         }  
  11.         function controllerTwo($scope, $rootScope) {  
  12.             $scope.name2 = $rootScope.name;  
  13.         }  
  14.     </script>  
  15. </head>  
  16. <body>  
  17.     <div style="border: 5px solid gray; width: 300px;">  
  18.         <div ng-controller="controllerOne">  
  19.             Setting the rootscope in controllerOne  
  20.         </div>  
  21.         <div ng-controller="controllerTwo">  
  22.             Hello, {{name2}}!  
  23.         </div>  
  24.         <br />  
  25.     </div>  
  26. </body>  
  27. </html>  
As we know, Rootscope is the top-level data container in AngularJs, we can keep any data in rootscope and read it when needed.

Using a Service

Using a service, we can set the value in one controller and read it from another controller.

The following is the sample code snippet: 

 
  1. <html ng-app="App">  
  2. <head>  
  3.     <title>Passing Data in Controllers</title>  
  4.     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>  
  5.     <script>  
  6.   
  7.         var app = angular.module('App', []);  
  8.         app.factory('TestService'function () {  
  9.             var TestService = {  
  10.                 Value: ' Default Value Set in Test Service'  
  11.             };  
  12.             return TestService;  
  13.         });  
  14.   
  15.         app.controller('controllerOne'function ($scope, TestService) {  
  16.             $scope.Value = TestService.Value;  
  17.             TestService.Value = 'I am from controllerOne';  
  18.         });  
  19.   
  20.         app.controller('controllerTwo'function ($scope, TestService) {  
  21.             $scope.Value = TestService.Value;  
  22.         });  
  23.   
  24.     </script>  
  25. </head>  
  26. <body>  
  27.     <div style="border: 5px solid gray; width: 400px;">  
  28.         <div ng-controller="controllerOne">Controller 1: {{Value}}</div>  
  29.         <div ng-controller="controllerTwo">Controller 2: {{Value}}</div>  
  30.     </div>  
  31. </body>  
  32. </html>  

Using $emit and $on

It dispatches the event upwards using the scope hierarchy.

We will see three controllers named Controllerone, ControllerTwo and ControllerThree. From the ControllerTwo and ControllerThree we will pass some values to Controllerone.

 
  1. <html ng-app="App">  
  2. <head>  
  3.     <title>Passing Controller values</title>  
  4.     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>  
  5.     <script>  
  6.   
  7.         var App = angular.module('App', []);  
  8.         //Controllerone  
  9.         App.controller('Controllerone', Controllerone);  
  10.         Controllerone.$inject = ["$scope"];  
  11.         function Controllerone($scope) {  
  12.   
  13.             $scope.$on('cityValue'function (events, data) {  
  14.                 $scope.city = data;  
  15.             });  
  16.   
  17.             $scope.$on('addressValue'function (events, data) {  
  18.                 $scope.address = data;  
  19.             });  
  20.         }  
  21.         //ControllerTwo  
  22.   
  23.         App.controller('ControllerTwo', ControllerTwo);  
  24.        ControllerTwo.$inject = ['$scope'];  
  25.   
  26.        function ControllerTwo($scope) {  
  27.             $scope.getCity = function (city) {  
  28.   
  29.                 $scope.$emit('cityValue', city);  
  30.             }  
  31.        }  
  32.         //ControllerThree  
  33.         App.controller('ControllerThree', ControllerThree);  
  34.         ControllerThree.$inject = ["$scope"];  
  35.         function ControllerThree($scope) {  
  36.             $scope.getAddrress = function (addr) {  
  37.                 $scope.$emit('addressValue', addr);  
  38.             }  
  39.         }  
  40.     </script>  
  41. </head>  
  42. <body ng-app="App">  
  43.     <div style="border: 5px solid gray; width: 500px;">  
  44.         <u>Controller One </u>  
  45.         <div ng-controller="Controllerone">  
  46.          <p><b>Getting City from ControllerTwo :</b> {{city}} </p>   
  47.           <p> <b>Getting Address from ControllerThree :</b>  {{address}}</p>  
  48.      
  49.     <div ng-controller="ControllerTwo">  
  50.         <p>Controller Two </p>  
  51.          City :<input type="text" ng-model="city" />  
  52.       <button ng-click="getCity(city)">Pass City to Controllerone </button  
  53.     </div>  
  54.             <p>Controller Three </p>  
  55.             <div ng-controller="ControllerThree">  
  56.               Address:  <input type="text" ng-model="address" />  
  57.                 <button ng-click="getAddrress(address)"> Pass Address to Controllerone</button>  
  58.             </div>  
  59.             <br />  
  60.         </div>  
  61.     </div>  
  62. </body>  
  63. </html>  

In ControllerTwo the following code sends the value to Controllerone using $emit and that is captured using $on in Controllerone.

  1. function ControllerTwo($scope) {  
  2.   
  3.    $scope.getCity = function (city) {  
  4.   
  5.       $scope.$emit('cityValue', city);  
  6.   
  7.    }  
  8.   
  9. }  
  10.   
  11. $scope.$on('cityValue', function (events, data) {  
  12.   
  13.    $scope.city = data;  
  14.   
  15. }); 

These are the various ways to communicate across controllers in AngularJs. Thanks for reading.