AngularJS $http and logger Circular Dependency
/Error
[$injector:cdep] Circular dependency found: $rootScope <- $http <- logger <- $exceptionHandler <- $rootScope <- $location <- routehelper
TLDR:
If you are looking for RequireJS's easy way to late-bind a dependency, here's how you do it in AngularJS.
var $http = angular.injector(['ng']).get('$http');
Story
I imagine this could be a fairly common scenario.
You implemented AngularJS, with a logger service.
angular .module('blocks.logger') .factory('logger', logger); logger.$inject = ['$log']; function logger($log) { var service = { error : error, log : $log.log }; return service; ///////////////////// function error(message, data, title) { $log.error('Error: ' + message, data); } }
You want to try to catch errors and log it back to your webservice
So add a REST call.
logger.$inject = ['$log', '$http']; function logger($log, $http) { // snip. function error(message, data) { $log.error('Error: ' + message, data); var request = { method : 'POST', url: _spPageContextInfo.webServerRelativeUrl + '/_layouts/MyLogService.svc/LogMessage', data: { 'log': message, 'event': 'error', 'meta': angular.toJson(data) }, dataType: "json", headers: { "Content-Type": "application/json; charset=utf-8" } }; $http(request); } }
Error!
[$injector:cdep] Circular dependency found: $rootScope <- $http <- logger <- $exceptionHandler <- $rootScope <- $location <- routehelper
I actually quite like this error. It's telling me the dependency tree starting from routehelper and looping around to $rootScope
Bingle will tell you to re-architect your solution so you have proper separation of concerns. But to be honest, I just want to log an error…
So here's how you do it.
var ng = angular.injector(['ng']); var $http = ng.get('$http');
Final Code Summary
logger.$inject = ['$log']; function logger($log) { // snip. function error(message, data) { $log.error('Error: ' + message, data); // inject $http here. var $http = angular.injector(['ng']).get('$http'); if (!$http) return; var request = { method : 'POST', url: _spPageContextInfo.webServerRelativeUrl + '/_layouts/MyLogService.svc/LogMessage', data: { 'log': message, 'event': 'error', 'meta': angular.toJson(data) }, dataType: "json", headers: { "Content-Type": "application/json; charset=utf-8" } }; $http(request); } }