title: UI Router: How should you prevent toState from showing while you're checking authorization?
body: <p>Edit: The proposed approach of using <code>resolve</code> isn't working for me. The <code>$stateChangeStart</code> event seems to be happening before the resolve stuff. <a href="http://plnkr.co/edit/WJaWJ8NSGDeg8Jfzi86R?p=preview" rel="nofollow">Plunker</a>.</p>
  
  <p>I'm using <code>$on($stateChangeStart)</code> to do authentication for routes. The way I was doing it, there was a problem: if an user was trying to access a state he's unauthorized to see, the state would be shown briefly before my code redirected him.</p>
  
  <p>To get around this, the best way seems to be to use <code>event.preventDefault()</code> + <code>$state.go(toState.name, {}, { notify: false })</code>, but <code>{ notify: false }</code> has a <a href="https://github.com/angular-ui/ui-router/issues/1158" rel="nofollow">known bug</a>.</p>
  
  <p>I'm not sure what a good way of handling this situation is. The only idea I've got is to toggle the <code>display</code> property of <code>body</code>, but I don't like that solution.</p>
  
  <ol>
  <li>The "flickering" <code>display: none</code> -> <code>display: block</code> on <code>body</code>.</li>
  <li>It's expensive to hide and redisplay such a large portion of the DOM (or is it?).</li>
  </ol>
  
  <p>How should this situation be handled?</p>
  
  <p><a href="http://plnkr.co/edit/XOYgggv2kjMoH2p11vnM?p=preview" rel="nofollow">Plunker</a></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>angular
    .module('app', ['ui.router'])
    .config(config)
    .run(run)
  ;
  
  function config($locationProvider, $urlRouterProvider, $stateProvider) {
    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('/');
    
    $stateProvider
      .state('home', {
        url: '/',
        template: '&lt;p&gt;home&lt;/p&gt;'
      })
      .state('one', {
        url: '/one',
        template: '&lt;p&gt;one&lt;/p&gt;',
        authenticate: true
      })
      .state('two', {
        url: '/two',
        template: '&lt;p&gt;two&lt;/p&gt;'
      })
    ;
  }
  
  function run($rootScope, $state, $timeout) {
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
      if (toState.authenticate) {
        // event.preventDefault();
        angular.element(document.body).css('display', 'none');
        if (isAuthenticated(false)) {
          // $state.go(toState.name, {}, { notify: false });
          angular.element(document.body).css('display', 'block');
        }
        else {
          $timeout(function() {
            $state.go('two');
            angular.element(document.body).css('display', 'block');
          }, 2000);
        }
      }
    });
  }
  
  function isAuthenticated(hardcode) {
    return hardcode; 
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html ng-app='app'&gt;
  
    &lt;head&gt;
      &lt;script data-require="angular.js@1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"&gt;&lt;/script&gt;
      &lt;script data-require="ui-router@0.2.11" data-semver="0.2.11" src="https://rawgit.com/angular-ui/ui-router/0.2.11/release/angular-ui-router.js"&gt;&lt;/script&gt;
      &lt;link rel="stylesheet" href="style.css" /&gt;
      &lt;script src="script.js"&gt;&lt;/script&gt;
      &lt;base href='/'&gt;
    &lt;/head&gt;
  
    &lt;body&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a ui-sref='home'&gt;home&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a ui-sref='one'&gt;state one&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a ui-sref='two'&gt;state two&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;div ui-view&gt;&lt;/div&gt;
    &lt;/body&gt;
  
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>