Reputation: 774
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();
}
}
}
})();
Upvotes: 1
Views: 560
Reputation: 3088
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);
}
}
Upvotes: 3