The [$injector:cdep]
Circular Dependency Detected error in AngularJS occurs when two or more components (services, factories, or providers) depend on each other in a loop. This leads to an infinite dependency injection loop, causing AngularJS to throw this error.
1. Understanding Circular Dependency in AngularJS
Error Message in Console:
Error: [$injector:cdep] Circular dependency found: serviceA <- serviceB <- serviceA
What This Means:
serviceA
depends onserviceB
, butserviceB
also depends onserviceA
.- This creates a loop (A → B → A), and AngularJS cannot resolve the dependencies.
2. Common Causes & Fixes
1. Direct Circular Dependency Between Two Services
Issue:
If two services inject each other, AngularJS cannot resolve the dependencies.
Incorrect Code (Circular Dependency Loop)
angular.module('myApp', [])
.service('serviceA', function(serviceB) { // serviceA depends on serviceB
this.getMessage = function() {
return serviceB.getMessage();
};
})
.service('serviceB', function(serviceA) { // serviceB depends on serviceA
this.getMessage = function() {
return "Message from B";
};
});
Fix: Use a third-party mediator service or defer execution.
✔ Solution 1: Use a Third Service (Mediator Pattern)
angular.module('myApp', [])
.service('serviceMediator', function() {
this.getMessage = function() {
return "Message from Mediator";
};
})
.service('serviceA', function(serviceMediator) {
this.getMessage = function() {
return serviceMediator.getMessage();
};
})
.service('serviceB', function(serviceMediator) {
this.getMessage = function() {
return serviceMediator.getMessage();
};
});
✔ Solution 2: Use $injector
for Lazy Injection
angular.module('myApp', [])
.service('serviceA', function($injector) {
this.getMessage = function() {
var serviceB = $injector.get('serviceB'); // Lazy injection
return serviceB.getMessage();
};
})
.service('serviceB', function() {
this.getMessage = function() {
return "Message from B";
};
});
Why $injector.get()
Works?
$injector.get()
delays the dependency resolution until it’s actually needed.- This breaks the loop because AngularJS doesn’t resolve
serviceB
immediately.
2. Circular Dependency in Factories
Issue:
Factories can also create circular dependencies if they depend on each other directly.
Incorrect Code:
angular.module('myApp', [])
.factory('factoryA', function(factoryB) {
return {
getData: function() {
return factoryB.getData();
}
};
})
.factory('factoryB', function(factoryA) {
return {
getData: function() {
return "Data from B";
}
};
});
Fix: Use a third-party service or defer execution with $injector
(as shown in services).
✔ Solution 1: Refactor with a Mediator Service
angular.module('myApp', [])
.factory('commonService', function() {
return {
getData: function() {
return "Common Data";
}
};
})
.factory('factoryA', function(commonService) {
return {
getData: function() {
return commonService.getData();
}
};
})
.factory('factoryB', function(commonService) {
return {
getData: function() {
return commonService.getData();
}
};
});
3. Circular Dependency in Controllers
Issue:
- If two controllers depend on each other (e.g., by using
ng-controller
inside anotherng-controller
), this can cause circular references.
Incorrect Code:
<div ng-controller="ControllerA">
<div ng-controller="ControllerB"></div>
</div>
angular.module('myApp', [])
.controller('ControllerA', function($scope, ControllerB) { // Circular reference
$scope.message = ControllerB.getMessage();
})
.controller('ControllerB', function($scope, ControllerA) { // Circular reference
$scope.message = "Hello from B";
});
Fix: Avoid direct controller-to-controller dependencies. Instead, use a shared service.
✔ Solution: Use a Shared Service
angular.module('myApp', [])
.service('sharedService', function() {
this.getMessage = function() {
return "Shared Service Message";
};
})
.controller('ControllerA', function($scope, sharedService) {
$scope.message = sharedService.getMessage();
})
.controller('ControllerB', function($scope, sharedService) {
$scope.message = sharedService.getMessage();
});
4. Circular Dependency in Directives
Issue:
If two directives depend on each other, they can create a circular dependency.
Incorrect Code:
angular.module('myApp', [])
.directive('directiveA', function(directiveB) { // Circular reference
return {
template: "<div>Directive A</div>"
};
})
.directive('directiveB', function(directiveA) { // Circular reference
return {
template: "<div>Directive B</div>"
};
});
Fix: Avoid direct directive-to-directive dependencies. Instead, use a common service.
✔ Solution: Use a Shared Service
angular.module('myApp', [])
.service('directiveService', function() {
this.getMessage = function() {
return "Shared Message";
};
})
.directive('directiveA', function(directiveService) {
return {
template: "<div>{{message}}</div>",
controller: function($scope) {
$scope.message = directiveService.getMessage();
}
};
})
.directive('directiveB', function(directiveService) {
return {
template: "<div>{{message}}</div>",
controller: function($scope) {
$scope.message = directiveService.getMessage();
}
};
});
3. Debugging Circular Dependencies
🔎 Steps to Debug in Chrome DevTools
- Check Console Errors → Open Developer Tools (F12) → Look for
[$injector:cdep]
errors. - Use AngularJS Dependency Tree Check
Run this in the console:angular.module('myApp')._invokeQueue
- This lists all services, factories, and directives.
- If a dependency is listed twice, it might be part of a circular loop.
- Use
$injector.annotate()
to Check Dependenciesangular.injector(['myApp']).annotate(function(myService) {});
- If this throws an error,
myService
is part of a circular dependency.
- If this throws an error,