17

When I try inject $http into an overridden factory I get the error:

Uncaught Error: [$injector:cdep] Circular dependency found: $http <- $exceptionHandler <- $rootScope

AngularModule.factory('$exceptionHandler',  function ($http) {

any ideas how to resolve? if I inject using [], $http is undefined

edit__________________

as per an answer below I tried:

MyModule.config(function($provide, $http) {
    $provide.decorator("$exceptionHandler", function($delegate) {
        return function(exception, cause) {..

but I still get the circular error:

Uncaught Error: [$injector:cdep] Circular dependency found: $http <- $exceptionHandler <- $rootScope

FutuToad
  • 2,750
  • 5
  • 36
  • 63
  • 1
    I am not sure why do you inject $http into a core factory? No wonder you get a circular DI. Perhaps create a custom factory in which you inject both $exceptionHandler and $http ? – Alex C Mar 11 '14 at 17:42
  • @AlexC well by default I just want to use $http to log serverside.. – FutuToad Mar 11 '14 at 17:46
  • .factory('My', function () { }) .factory('$exceptionHandler', function ($log,My) { }) works if you pass $http on My I get Error: [$injector:cdep] http://errors. – Whisher Mar 11 '14 at 18:02
  • @FutuToad would `$decorate` be the right thing here, if you're trying to overload the functionality of something like `$log`? – c0bra Mar 11 '14 at 18:15
  • @c0bra yeah, can you check my edit – FutuToad Mar 12 '14 at 10:35

3 Answers3

26

Inject the $injector and then get the $http service from there. Something like this:

AngularModule.factory('$exceptionHandler',  function ($injector) {
    var $http = $injector.get("$http");

See https://groups.google.com/forum/#!topic/angular/lbFY_14ZtnU/discussion

However, this will completely override the $exceptionHandler functionality provided by Angular. If you just want to add the server-side log to the existing functionality, see this question about augmenting $exceptionHandler functionality.

Community
  • 1
  • 1
dnc253
  • 39,967
  • 41
  • 141
  • 157
  • 6
    unfortunately I can't do this either: **var $http = $injector.get("$http");** I get the error **$http <- $exceptionHandler <- $rootScope** – FutuToad Mar 12 '14 at 14:23
  • 1
    I don't think the circular dependency is coming from the $injector. I've gotten around many circular dependencies by getting them straight from the $injector. Make sure you still aren't trying to wire in $http anywhere in this $exceptionHandler stuff. – dnc253 Mar 12 '14 at 15:03
  • thanks, you mean like this: $provide.decorator("$exceptionHandler", function($delegate,$injector) { return function(exception, cause) { var $http = $injector.get("$http"); – FutuToad Mar 12 '14 at 15:13
  • that way seems to work, I get the $http function, but for some reason though when I try the **$http.get().always**, I get TypeError: Object # has no method 'always' – FutuToad Mar 12 '14 at 15:27
  • 1
    @FutuToad I think dnc253 is right. Check this plunker: http://plnkr.co/edit/0ilJj4?p=preview Also, $q has `finally`, not `always`. – c0bra Mar 12 '14 at 15:35
  • @c0bra thanks, got a bit confused as I saw complete somewhere in the docs – FutuToad Mar 12 '14 at 16:20
  • This works, but only if you don't minify the code, which screws over the references here. – monksy Sep 22 '14 at 16:52
  • 1
    If minifying the code, you have to use the array notation just like anywhere else. (`['$injector', function ($injector) { ...`) – dnc253 Sep 22 '14 at 22:02
  • 1
    For me `var $http = $injector.get("$http");` actually didn't work, it was still resolving the dependency too soon. A simple, albeit also not pretty, alternative is to do `$injector.get("$http").get(....);` in the actual logic. – Constantijn Schepens Apr 26 '17 at 12:28
4

I'm using this solution, because of circular dependency issues with rootScope:

angular
  .module('facilityLog')
  .provider('$exceptionHandler', function() {
 "use strict";

 this.$get = function($injector) {

  function exceptionHandler(exception, cause) {
   // This is the part where you get the instance of $http in your case
   var $rootScope = $injector.get('$rootScope');
   //...
  }

  return exceptionHandler;

}});

So if you request the instance inside the exceptionHandler-Function you will not get the circular dependency-error.

Sebastian
  • 2,874
  • 25
  • 31
2

I used the following to solve this. Note how the array notation is used to make this minification safe. Note also, that I am completely overriding the $esceptionHandler and using my own service to replace it.

angular
    .module('app')
    .factory('$exceptionHandler', $exceptionHandler);

$exceptionHandler.$inject = ['$injector', 'exceptionLoggingService'];

function $exceptionHandler($injector, exceptionLoggingService)
{
    return function(exception, cause)
    {
        exceptionLoggingService.http = exceptionLoggingService.http || $injector.get('$http');
        exceptionLoggingService.error(exception, cause);
    };
}
Kildareflare
  • 4,590
  • 5
  • 51
  • 65