title: Detect ui-router state change from within controller and close Modal accordingly
body: <p>I open a UI-Bootstrap Modal using the <code>$modal.open({...})</code> method. I need this to close when the user presses the <strong>back button</strong>.</p>
  
  <p>The <code>result</code> promise returned by the <code>open()</code> method is not useful in this case as it cannot detect the state change due to the back button. Right now when the back button is pressed, the state changes but the modal stays open.</p>
  
  <p>Basically I am having the exact problem as <a href="https://stackoverflow.com/questions/23480377/need-to-close-a-modal-on-state-exit">this question</a> but even though it has a selected answer, the problem is not solved as evidenced from the comments. <a href="https://stackoverflow.com/questions/25298246/modal-ui-router-hitting-escape-changing-state">This other question</a> is similar but also doesn't solve the <strong>back button</strong> issue.</p>
  
  <p>I need some way to detect that the current state has changed from within the controller and call <code>$modalInstance.close()</code> or the <code>$scope.$close()</code> methods.</p>
  
  <p>I could listen for <code>$stateChangeStart</code> event and check the <code>fromState</code> argument to conditionally close the modal. But then this event would unnecessarily keep firing for all subsequent state changes too.</p>
  
  <p><strong>UPDATE:</strong> So I tried listening for the event and deregistered it as soon as it is fired for the first time. This way I get to listen for the back button state change and then stop it when I want. The final code for the modal state is as follows:</p>
  
  <pre><code>$stateProvider.state('itemList.itemNew', {
      url: '/new',
      onEnter: function($state, $modal) {
          $modal.open({
              templateUrl: "/static/partials/item/form.html",
              controller: function($http, $scope, $modalInstance) {
                  $scope.editableItem = {};
                  $scope.saveItem = function(item) {
                      $http.post('/api/item', item)
                      .success(function(data) {
                          $modalInstance.close(data);
                          alert("Saved Successfully");
                      }).error(function(data) {
                          alert("There was an error.");
                      });
                  };
                  //Register listener specifically for the back button :(
                  deRegister = $scope.$on('$stateChangeSuccess', 
                      function(event, toState, toParams, fromState, fromParams) {
                          if (toState.name === 'itemList' &amp;&amp; 
                              fromState.name === 'itemList.itemNew') {
                              $modalInstance.close();//Close the modal
                              deRegister();//deRegister listener on first call
                          }
                      }
                  );
              }
          }).result.then(function() {
              //Promise Resolved, Modal Closed.. So reload
              $state.go("^", null, {
                  "reload": true
              });
          }, function() {
              //Promise Rejected, Modal Dismissed.. no reload
              $state.go("^");
          });
      },
  });
  </code></pre>
  
  <p>I still think there should be a better way to do it. <a href="https://stackoverflow.com/users/2394888/constellates">Constellates</a> apparently decided to dump <code>modal.js</code> from ui-bootstrap altogether. Should I do the same and simply render the modal using plain Bootstrap CSS out of a <code>&lt;ui-view/&gt;</code>?</p>