简体   繁体   中英

Angular.js circular dependency error in ui-router wrapper

I'm following John Papa's angular style guide ( https://github.com/johnpapa/angular-styleguide#routing ) and using a custom wrapper around the angular ui-router provided in this guide. However, the wrapper does not work for me and I get a circular dependency error when injecting $state:

Uncaught Error: [$injector:cdep] Circular dependency found: $rootScope <- $timeout <- $$rAF <- $$animateQueue <- $animate <- toastr <- logger <- $exceptionHandler <- $rootScope <- $state <- routerHelper

I have tried injecting $state manually using $injector but that gives me an unknown provider error.

Here is the code:

(function() {
'use strict';

angular
    .module('blocks.router')
    .provider('routerHelper', routerHelperProvider);

routerHelperProvider.$inject = ['$locationProvider', '$stateProvider', '$urlRouterProvider', '$injector'];

function routerHelperProvider($locationProvider, $stateProvider, $urlRouterProvider) {


    this.$get = RouterHelper;

    $locationProvider.html5Mode(true);

    RouterHelper.$inject = ['$state'];

    function RouterHelper($state) {
        var hasOtherwise = false;

        var service = {
            configureStates: configureStates,
            getStates: getStates
        };

        return service;

        function configureStates(states, otherwisePath) {
            states.forEach(function (state) {
                $stateProvider.state(state.state, state.config);
            });
            if (otherwisePath && !hasOtherwise) {
                hasOtherwise = true;
                $urlRouterProvider.otherwise(otherwisePath);
            }
        }

        function getStates() {
            return $state.get();
        }
    }

}
})(); 

I think this is a problem with toastr and not the UI router code.

John Papa bases his examples off the plain 'toastr' package and not the 'angular-toastr' package.

toastr: https://github.com/CodeSeven/toastr

angular-toastr: https://github.com/Foxandxss/angular-toastr

With the 'toastr' package he registers the global instance of toastr using a constant:

    .module('app.core')
    .constant('toastr', toastr);

Which makes it available for injection into the logger service:

logger.$inject = ['$log', 'toastr'];

/* @ngInject */
function logger($log, toastr) {

However if you use the angular-toastr package, the toastr object introduces a set of dependencies upon some angular objects:

$rootScope <- $timeout <- $$rAF <- $$animateQueue <- $animate <- toastr

And this causes a circular dependency because the $rootScope has exception handling which uses the logger/toastr objects:

toastr <- logger <- $exceptionHandler <- $rootScope

I wasn't sure how to properly refactor this to remove the circular dependency. So as a temporary workaround, I changed the logger service to delay resolution of the toastr dependency using $injector. Not ideal, but I was able to move on to other pressing concerns.

logger.$inject = ['$log', '$injector']; // 'toastr'

/* @ngInject */
function logger($log, $injector) { // toastr

    var service = {
        showToasts: true,

        info    : info,
        success : success,
        warning : warning,
        error   : error,

        // straight to console; bypass toastr
        log     : $log.log
    };

    return service;
    /////////////////////


    function info(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.info(message, title);
        $log.info('Info: ' + message, data);
    }

    function success(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.success(message, title);
        $log.info('Success: ' + message, data);
    }

    function warning(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.warning(message, title);
        $log.warn('Warning: ' + message, data);
    }

    function error(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.error(message, title);
        $log.error('Error: ' + message, data);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM