ui-router: [bug] Child state with stateParams will load controller twice if stateParam absent

Hard to explain, so I’ve whipped up a minimal repro

Go to index.html#/bar Click the baz button and watch the console.log. It will print out the scope twice. Whats worse is one of these scopes is orphaned after the digest and loses its $parent.

If the baz 1 is clicked, the id route param is supplied and the bug is not occur.

Also, would it be worth defaulting toParams in transitionTo(to, toParams) to {} so the user does not need to specify the empty object for when params should be empty.

I tried finding the bug myself but I couldn’t find it and don’t have the time to investigate further.

Thanks 😃

<!doctype html>
<html lang="en" ng-app="repro">
  <head>
    <script src="angular-1.1.4.js"></script>
    <script src="angular-ui-states.js"></script>
  </head>
  <body>
    <div ui-view></div>
  </body>
  <script>
  angular.module('repro', ['ui.state'])
    .config(['$stateProvider', function ($stateProvider) {
        $stateProvider
          .state('foo', {
            url: '',
            template: 'foo <div ui-view><' + '/div>',
            controller: ['$scope', function($scope) { $scope.name = 'foo'; }]
          })
          .state('foo.baz', {
            url: '/baz/:id',
            template: 'baz',
            controller: ['$scope', function($scope) {
              $scope.name = 'baz';
              console.log('scope', $scope);
            }]
          })
          .state('foo.bar', {
            url: '/bar',
            template: 'bar -> <button ng-click="a()">baz<' + '/button><br>bar -> <button ng-click="b()">baz 1<' + '/button>',
            controller: ['$scope', '$state', function($scope, $state) {
              $scope.name = 'bar';
              $scope.a = function() {
                $state.transitionTo('foo.baz', {});
              };
              $scope.b = function() {
                $state.transitionTo('foo.baz', {id: 1});
              };
            }]
          });
    }]);
  </script>
</html>

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 77 (59 by maintainers)

Commits related to this issue

Most upvoted comments

So if you have:

.state('search', {
  url: '/search?query',
  reloadOnSearch: false
})

Then in you app you can use $location.search({query: 'kittens'}) to change the query param in the url but not reactivate the state over and over.