AngularJS provides a built-in event-handling system that allows different components (controllers, directives, services, etc.) to communicate with each other using events. The two main methods used for event communication within the $scope
are:
$scope.$on(eventName, callback)
– Listens for an event.$scope.$broadcast(eventName, data)
– Broadcasts an event downward (from parent to child scopes).$scope.$emit(eventName, data)
– Sends an event upward (from child to parent scopes).
This article will focus on $scope.$on()
and $scope.$broadcast()
.
1. What is $scope.$on()
?
$scope.$on()
is used to listen for an event. It waits for a particular event name and executes the provided callback function when the event occurs.
Syntax:
$scope.$on('eventName', function(event, data) {
// Handle the event
});
eventName
→ Name of the event to listen for.event
→ Event object that contains metadata.data
→ Optional data sent with the event.
2. What is $scope.$broadcast()
?
$scope.$broadcast()
is used to send an event from a parent scope to all its child scopes.
Syntax:
$scope.$broadcast('eventName', { key: 'value' });
eventName
→ Name of the event.data
→ Optional data to send.
Note: $broadcast()
does not propagate upwards; it only sends events downward in the scope hierarchy.
3. Example: Parent-to-Child Communication
Let’s see an example where a parent controller broadcasts an event and a child controller listens to it.
Example:
<div ng-app="myApp" ng-controller="ParentController">
<button ng-click="sendMessage()">Send Message</button>
<div ng-controller="ChildController">
<p>Message from Parent: {{ message }}</p>
</div>
</div>
JavaScript (AngularJS)
var app = angular.module('myApp', []);
// Parent Controller
app.controller('ParentController', function($scope) {
$scope.sendMessage = function() {
$scope.$broadcast('customEvent', { text: 'Hello from Parent!' });
};
});
// Child Controller
app.controller('ChildController', function($scope) {
$scope.$on('customEvent', function(event, data) {
$scope.message = data.text;
});
});
How it Works?
- When the button is clicked,
sendMessage()
triggers$scope.$broadcast()
. - The child controller (
ChildController
) listens for the event using$scope.$on()
. - The message is updated in the child scope.
4. Example: Sending Data with $broadcast()
We can pass data along with the event.
Example:
$scope.$broadcast('userLoggedIn', { username: 'JohnDoe' });
$scope.$on('userLoggedIn', function(event, data) {
console.log('User:', data.username); // Output: JohnDoe
});
Why use this?
- It helps in updating multiple child controllers when an event occurs.
- Useful in scenarios like theme changes, user login/logout, language selection, etc.
5. Example: Nested Controllers
Let’s see an example with nested controllers.
<div ng-controller="MainController">
<button ng-click="notifyChildren()">Notify Children</button>
<div ng-controller="ChildController1">
<p>Child 1: {{ message }}</p>
</div>
<div ng-controller="ChildController2">
<p>Child 2: {{ message }}</p>
</div>
</div>
JavaScript:
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.notifyChildren = function() {
$scope.$broadcast('notifyEvent', { text: 'Hello, Children!' });
};
});
app.controller('ChildController1', function($scope) {
$scope.$on('notifyEvent', function(event, data) {
$scope.message = data.text;
});
});
app.controller('ChildController2', function($scope) {
$scope.$on('notifyEvent', function(event, data) {
$scope.message = data.text;
});
});
How it Works?
- When the button is clicked in
MainController
, it triggers$scope.$broadcast()
. - Both child controllers (
ChildController1
andChildController2
) listen for the event and update their scope variables accordingly.
6. $scope.$broadcast()
vs $scope.$emit()
Feature | $scope.$broadcast() | $scope.$emit() |
---|---|---|
Direction | Sends event downward (parent to children) | Sends event upward (child to parent) |
Use Case | Notify child controllers | Notify parent controllers |
Propagation | Goes down the scope tree | Goes up the scope tree |
Example Using $scope.$emit()
$scope.$emit('myEvent', { msg: 'Hello, Parent!' });
$scope.$on('myEvent', function(event, data) {
console.log('Received:', data.msg);
});
Use $emit()
when:
- A child controller needs to communicate upward to its parent.
7. Cleaning Up $scope.$on()
Listeners
When using $scope.$on()
, always clean up the event listener to avoid memory leaks.
How to Remove Event Listeners?
var unbind = $scope.$on('customEvent', function(event, data) {
console.log(data);
});
$scope.$on('$destroy', unbind);
📌 Why clean up?
- Prevents performance issues.
- Avoids duplicate event listeners when controllers are destroyed and recreated.