In AngularJS, when a controller or directive is removed from the DOM, its associated $scope
should be properly cleaned up to avoid memory leaks. The $scope.$on('$destroy')
method is used to handle cleanup tasks such as:
Unbinding event listeners
Canceling timers ($timeout
and $interval
)
Removing DOM elements
Cleaning up watchers ($watch
)
1. Unbinding Event Listeners
If you bind an event using $scope.$on()
, you must unbind it when the scope is destroyed.
Example:
var eventHandler = $scope.$on("customEvent", function(event, data) {
console.log("Event received:", data);
});
// Cleanup on destroy
$scope.$on("$destroy", function() {
eventHandler();
console.log("Event listener removed");
});
Why?
Leaving event listeners active after the scope is destroyed can cause memory leaks and unexpected behavior.
2. Canceling $timeout
and $interval
AngularJS’s $timeout
and $interval
functions need to be manually canceled when a scope is destroyed.
Example:
var timer = $timeout(function() {
console.log("Task executed");
}, 5000);
$scope.$on("$destroy", function() {
$timeout.cancel(timer);
console.log("Timeout canceled");
});
Similarly, for $interval
:
var interval = $interval(function() {
console.log("Repeating task");
}, 1000);
$scope.$on("$destroy", function() {
$interval.cancel(interval);
console.log("Interval canceled");
});
Why?
If not canceled, these timers will continue running, consuming resources unnecessarily.
3. Removing DOM Elements
If you dynamically create DOM elements in your AngularJS app, remove them when no longer needed.
Example:
var element = angular.element("<div>Dynamic Element</div>");
angular.element(document.body).append(element);
$scope.$on("$destroy", function() {
element.remove();
console.log("DOM element removed");
});
Why?
Preventing orphaned DOM elements helps free up memory.
4. Cleaning Up Watchers
If you use $watch
, it keeps monitoring changes indefinitely. Unwatch when it’s no longer required.
Example:
var unwatch = $scope.$watch("data", function(newValue, oldValue) {
console.log("Data changed:", newValue);
});
$scope.$on("$destroy", function() {
unwatch();
console.log("Watcher removed");
});
Why?
Too many active $watch
functions slow down the digest cycle, affecting performance.
5. Removing jQuery Event Listeners
If you’re using jQuery, always unbind event listeners.
Example:
var resizeHandler = function() {
console.log("Window resized");
};
$(window).on("resize", resizeHandler);
$scope.$on("$destroy", function() {
$(window).off("resize", resizeHandler);
console.log("jQuery event listener removed");
});
Why?
Failing to remove event listeners keeps objects in memory, causing potential memory leaks.
6. Cleaning Up Global Variables
If your AngularJS app interacts with global objects, clean them up.
Example:
window.someData = "Stored Data";
$scope.$on("$destroy", function() {
delete window.someData;
console.log("Global variable cleared");
});
Why?
Global variables are not garbage collected, so explicitly deleting them is crucial.
7. Cleaning Up Services
If services hold persistent references, reset them when not needed.
Example:
app.factory("SharedService", function() {
var data = {};
return {
set: function(key, value) {
data[key] = value;
},
get: function(key) {
return data[key];
},
clear: function() {
data = {};
}
};
});
$scope.$on("$destroy", function() {
SharedService.clear();
console.log("Service data cleared");
});
Why?
Prevents stale data from persisting in memory unnecessarily.