In AngularJS, multiple controllers often need to share data. Since controllers have isolated scopes, sharing data between them requires techniques like services, factories, events, and $rootScope
.
1️⃣ Using a Service (Best Practice )
Services provide a centralized way to share data between controllers. Since services are singletons, the same instance is shared across the app.
Example – Creating a Shared Service
// Define the service
app.service('SharedService', function() {
var sharedData = "Hello from Service!";
return {
getData: function() {
return sharedData;
},
setData: function(value) {
sharedData = value;
}
};
});
Controller 1: Updating Data
app.controller('ControllerA', function($scope, SharedService) {
$scope.updateData = function() {
SharedService.setData("Updated Data from Controller A");
};
});
Controller 2: Accessing Data
app.controller('ControllerB', function($scope, SharedService) {
$scope.sharedData = SharedService.getData();
});
Best Practice: Services ensure a single source of truth and maintain loose coupling.
2️⃣ Using a Factory (Similar to Service)
A factory works like a service but returns an object explicitly.
Example – Using a Factory to Share Data
app.factory('SharedFactory', function() {
var sharedData = { message: "Hello from Factory!" };
return {
getData: function() {
return sharedData.message;
},
setData: function(value) {
sharedData.message = value;
}
};
});
Factory vs. Service: Factories return an object, whereas services are instantiated using new
.
3️⃣ Using $rootScope
(Temporary, Not Recommended )
$rootScope
is globally available, making it a quick way to share data. However, overusing it can lead to maintenance issues.
Example – Using $rootScope
to Share Data
app.controller('ControllerA', function($scope, $rootScope) {
$rootScope.sharedData = "Hello from Controller A!";
});
app.controller('ControllerB', function($scope, $rootScope) {
$scope.dataFromA = $rootScope.sharedData;
});
Downside:
- Can lead to unexpected side effects.
- Harder to track changes.
- Performance impact when
$digest
runs.
Use $rootScope
only for global data (e.g., app-wide settings, authentication state).
4️⃣ Using $broadcast()
and $emit()
for Event-Based Communication
If controllers do not have a direct connection, use event-driven communication with $broadcast()
and $emit()
.
Example – Sending Data from Controller A
app.controller('ControllerA', function($scope, $rootScope) {
$scope.sendMessage = function() {
$rootScope.$broadcast('dataUpdated', "Message from Controller A");
};
});
Example – Listening for Data in Controller B
app.controller('ControllerB', function($scope) {
$scope.$on('dataUpdated', function(event, data) {
$scope.receivedData = data;
});
});
When to Use Events?
- When controllers do not share a direct connection.
- When loosely coupled modules need to communicate.
Downside:
- Harder to debug.
- Too many events can lead to performance issues.
5️⃣ Using a Parent Controller ($scope
Inheritance)
If controllers are nested, they inherit the parent $scope
.
Example – Parent Controller (MainController
)
app.controller('MainController', function($scope) {
$scope.sharedData = "Data from Parent";
});
Child Controller (Inherits MainController
Data)
app.controller('ChildController', function($scope) {
console.log($scope.sharedData); // Inherited from MainController
});
Example – View (HTML)
<div ng-controller="MainController">
<p>Main: {{ sharedData }}</p>
<div ng-controller="ChildController">
<p>Child: {{ sharedData }}</p>
</div>
</div>
Best for Hierarchical Controllers
Doesn’t Work for Unrelated Controllers
Best Approach: Use Services for Most Cases
Method | Use Case | Pros | Cons |
---|---|---|---|
Service ( Best) | Most recommended | Singleton, reusable, easy to maintain | None |
Factory ( Alternative) | Like services but returns an object | Singleton, flexible | Slightly more code |
$rootScope ( Temporary Use) | Global settings (e.g., themes) | Easy to access | Risky, hard to debug |
$broadcast/$emit ( Only for Events) | Unrelated controllers | Decoupled communication | Harder to track, debugging issues |
Parent Scope Inheritance ( Nested Only) | Parent-child controllers | Simple, direct | Only works in nested views |