<!doctype html>
<html lang="en" ng-app="myApp">

<head>
  <meta charset="UTF-8">
  <title>ui-router transitionTo bug</title>

  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css">

  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js"></script>

  <script src="https://rawgithub.com/angular-ui/ui-router/818b0d69d2063064ca6d2e3b05252200439862d3/release/angular-ui-router.js"></script>

  <script>
  /**
   * my custom build have the bug fixed
   * replace ui-router script src with
   *
   * //pc035860.github.io/ui-router/build/angular-ui-router.min.js
   */
  </script>

  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">

  <div class="container">
    <div class="nav-container">
      <ul class="nav nav-tabs">
        <li ng-class="{'active': $state.includes('route1')}">
          <a href="#/route1?d=4&e=5&f=6">Route1</a>
        </li>
        <li ng-class="{'active': $state.includes('route2')}">
          <a href="#/route2?c=1&b=2&a=3">Route2</a>
        </li>
      </ul>
    </div>
    <div ui-view style="min-height: 300px;"></div>

    <hr>

    <div class="inspect">
      <h3>location change log:</h3>
      <pre>{{ locationChgLog }}</pre>
    </div>

  </div>


</body>
</html>
<div class="route">

  <h2>Route1</h2>

  <p>
    Try <code>Route2</code> tab, see what happens in the <code>location change log</code>.
  </p>

  <p>&nbsp;</p>

  <h4>Parameters:</h4>
  <pre>{{ params }}</pre>

</div>
<div class="route">

  <h2>Route2</h2>

  <p>
    The link above for route2 is <code>#/route2?c=1&b=2&a=3</code>, of which order is different from the one set in <code>app.js</code>. <br>
    Then the <code>$state.transitionTo()</code> is triggered with third parameter <code>false</code>, meaning the state transition shouldn't change the location. <br>
    As you can see below, <code>$locationChangeSuccess</code> triggers twice.
  </p>

  <p>&nbsp;</p>

  <h4>Parameters:</h4>
  <pre>{{ params }}</pre>

</div>
angular.module('myApp', ['ui.router'])

.config(function ($stateProvider, $urlRouterProvider) {

  $urlRouterProvider.otherwise('/route1');

  $stateProvider

    .state('route1', {
      url: '/route1?d&e&f',
      templateUrl: 'route1.html'
    })

    .state('route2', {
      url: '/route2?a&b&c',
      templateUrl: 'route2.html'
    });

})

.run(function ($rootScope, $state) {
  $rootScope.$state = $state;
})

.controller('MainCtrl', function ($scope, $stateParams, $log) {

  $scope.locationChgLog = '';

  $scope.$stateParams = $stateParams;

  $scope.$watch('$stateParams', function(newValue, oldValue) {
    $scope.params = JSON.stringify(newValue, null, 2);
  }, true);

  $scope.$on('$stateChangeStart', function () {
    $scope.locationChgLog = '';
  });

  $scope.$on('$locationChangeSuccess', function () {
    var args = Array.prototype.slice.call(arguments);

    $scope.locationChgLog += (JSON.stringify({
        time: (new Date()).getTime(),
        from: args[2],
        to: args[1]
      }, null, 2) + '\n\n');
  });

});