Why is this Angular ui router code causing an infinite loop in $ digest?

I have welded the code as much as possible. Something about nested states and event handling / passing causes an endless loop. In Chrome, I can pause it and see that it loops forever in the Angular $digest function. Any idea why? Is this a mistake in my sample code or a bug in Angular or UI Router ?

 <!doctype html> <html ng-app='bugapp' ng-controller='BugAppCtrl'> <head> <script src='//code.jquery.com/jquery-1.10.1.min.js'></script> <!-- Angular 1.2.11 --> <script src='//ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js'></script> <!-- UI router 0.2.8 --> <script src='//cdn.jsdelivr.net/angular.ui-router/0.2.8/angular-ui-router.js'></script> <script> angular.module('bugapp', ['ui.router']) .run(function ($rootScope, $state, $stateParams) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; }) .config(function ($locationProvider, $stateProvider, $urlRouterProvider) { $locationProvider.html5Mode(false); $stateProvider .state("root", { abstract: true, url: "/servletContext?asUser", template: '<div ui-view></div>' // ??? }) .state("root.home", { abstract: true, url: "/home", template: "<div ng-if='hasData()' ui-view ></div>" }) .state("root.home.profile", { url: "/profile", template: '<div>whatever</div>' }) }) .controller('BugAppCtrl', function ($scope, $state, $stateParams, $log, $location) { $log.log('BugAppCtrl: constructor'); $scope.hasData = function() { var res = !!$scope.foo; // $log.log("hasData called, returing " + res + " foo is " + $scope.foo); return res; }; $scope.$on('$stateChangeSuccess', function () { $log.log("State changed! (to " + $state.current.name + ")"); $scope.foo = 'junk'; $scope.$broadcast("resetfoo"); }); $state.go('root.home.profile'); }); </script> </head> <body> <div ui-view></div> </body> </html> 
+5
source share
1 answer

I suspect this is a bug in the UI router for two reasons:

  • I tried your code, and then tried to downgrade the Router user interface to 0.2.7. When I used 0.2.7, it worked.
  • Even if you continue to use version 0.2.8 of the UI Router, if you perform a state change through $ location instead of $ state, it works. Here is an example of using $ location instead of calling $ state.go:

     $location.path('/servletContext/home/profile'); 

Although I use and recommend a UI Router (I can’t do without nested views), if you want to do any interceptions or redirects in the future when a user tries to go to certain pages, I recommend using $ location.path instead of $ state, for reasons which I described in a blog post

Change Previously, I did not try with the parameters, but simply tried with the code that you published (I created a second controller and assigned it to the state "root.home.profile") and it works. Instructions from the UI Router are here . But basically, if you set your URL in your state definition in the same way as with a UI router:

 url: "/profile/:foo", 

then in your call to $ location.path add the parameter to the path:

 $location.path('/servletContext/home/profile/12'); 

and you can access 12 in the controller from

 $stateParams.foo 
+5
source

All Articles