title: Pass a promise into an Angular-UI state controller
body: <p>Is it possible to pass a promise to a UI.Router <code>$state</code> from an outside controller (e.g. the controller that triggered the state)? </p>
  
  <p>I know that <code>$state.go()</code> returns a promise; is it possible to <strike>override that with your own promise</strike> resolve this promise directly yourself or resolve it using a new promise?</p>
  
  <p>Also, the documentation says the promise returned by <code>$state.go()</code> can be rejected with another promise (indicated by <code>transition superseded</code>), but I can't find anywhere that indicates how this can be done from within the state itself.</p>
  
  <p>For example, in the code below, I would like to be able to wait for the user to click on a button (<code>$scope.buttonClicked()</code>) before continuing on to <code>doSomethingElse()</code>.</p>
  
  <p>I know that I can emit an event, but since promises are baked into Angular so deeply, I wondered if there was a way to do this through <code>promise.resolve</code>/<code>promise.reject</code>.</p>
  
  <pre><code>angular.module('APP', ['ui.router'])
  .config(['$stateProvider', function ($stateProvider) {
      $stateProvider
      .state('myState', {
          template: '&lt;p&gt;myState&lt;/p&gt;',
          controller: ['$state', '$scope', '$q', function ($state, $scope, $q) {
              var deferred = $q.defer();
  
              $scope.buttonClicked = function () {
                  deferred.resolve();
              }
          }]
      });
  }])
  .controller('mainCtrl', ['$state', function ($state) {
      $state.go('myState')
      .then(doSomethingElse)
  }]);
  </code></pre>
  
  <hr>
  
  <p><strong>Update</strong>
  I have accepted @blint's answer as it has got me closest to what I wanted. Below is some code that fleshes out this answer's idea a bit more. I don't think the way I have written this is a very elegant solution and I am happy if someone can suggest a better way to resolve promises from a triggered state.</p>
  
  <p>The solution I've chosen is to chain your promises as you normally would in your controller, but leave a <code>$scope.next()</code> method (or something similar) attached to that scope that resolves/rejects the promise. Since the state can inherit the calling controller's scope, it will be able to invoke that method directly and thus resolve/reject the promise. Here is how it might work:</p>
  
  <p>First, set up your states with buttons/controllers that call a <code>$scope.next()</code> method:</p>
  
  <pre><code>.config(function ($stateProvider) {
      $stateProvider
      .state('selectLanguage', {
          template: '&lt;p&gt;Select language for app: \
              &lt;select ng-model="user.language" ng-options="language.label for language in languages"&gt;\
                  &lt;option value=""&gt;Please select&lt;/option&gt;\
              &lt;/select&gt;\
              &lt;button ng-click="next()"&gt;Next&lt;/button&gt;\
              &lt;/p&gt;',
          controller: function ($scope) {
              $scope.languages = [
                  {label: 'Deutch', value: 'de'},
                  {label: 'English', value: 'en'},
                  {label: 'Français', value: 'fr'},
                  {label: 'Error', value: null}
              ];
          }
      })
      .state('getUserInfo', {
          template: '&lt;p&gt;Name: &lt;input ng-model="user.name" /&gt;&lt;br /&gt;\
              Email: &lt;input ng-model="user.email" /&gt;&lt;br /&gt;\
              &lt;button ng-click="next()"&gt;Next&lt;/button&gt;\
              &lt;/p&gt;'
      })
      .state('mainMenu', {
          template: '&lt;p&gt;The main menu for {{user.name}} is in {{user.language.label}}&lt;/p&gt;'
      })
      .state('error', {
          template: '&lt;p&gt;There was an error&lt;/p&gt;'
      });
  })
  </code></pre>
  
  <p>Next, you set up your controller. In this case, I'm using a local service method, <code>user.loadFromLocalStorage()</code> to get the ball rolling (it returns a promise), but any promise will do. In this workflow, if the <code>$scope.user</code> is missing anything, it will progressively get populated using states. If it is fully populated, it skips right to the main menu. If elements are left empty or are in an invalid state, you get taken to an error view.</p>
  
  <pre><code>.controller('mainCtrl', function ($scope, $state, $q, User) {
      $scope.user = new User();
  
      $scope.user.loadFromLocalStorage()
      .then(function () {
          var deferred;
  
          if ($scope.user.language === null) {
               deferred = $q.defer();
  
               $state.go('selectLanguage');
  
               $scope.next = function () {
                  $scope.next = undefined;
  
                  if ($scope.user.language === null) {
                      return deferred.reject('Language not selected somehow');
                  }
  
                  deferred.resolve();
               };
  
               return deferred.promise;
          }
      })
      .then(function () {
          var deferred;
  
          if ($scope.user.name === null || $scope.user.email === null) {
              deferred = $q.defer();
  
              $state.go('getUserInfo');
              $scope.next = function () {
                  $scope.next = undefined;
  
                  if ($scope.user.name === null || $scope.user.email === null) {
                      return deferred.reject('Could not get user name or email');
                  }
  
                  deferred.resolve();
              };
  
              return deferred.promise;
          }
  
  
      })
      .then(function () {
          $state.go('mainMenu');
      })
      .catch(function (err) {
          $state.go('error', err);
      });
  
  });
  </code></pre>
  
  <p>This is pretty verbose and not yet very DRY, but it shows the overall intention of asynchronous flow control using promises.</p>