0

How can we use $transitions to cancel a state change to prompt the user for saving? Previous ui-router versions used to have an event in the callback, and could be stopped with event.preventDefault(), but this event seems to have disappeared.

I'm using this code in my controller:

var onTransitionStartOff = $transitions.onStart({}, function($transitions)
{
    if ($scope.itemTracker.hasChanged()) {
        $scope.itemTracker.askExitConfirm().then(function () {
            onTransitionStartOff();
            var toState = $transitions.$to();
            $state.go(toState);
        }, function () {});
        return $q.reject(null);
    }
    onTransitionStartOff();
});

It works great, but it leaves an error message in the console due to the rejected promise.

console error

I took a look in stateService.ts, but I didn't see some interesting things...

Mistalis
  • 17,793
  • 13
  • 73
  • 97
Robin Thoni
  • 1,651
  • 13
  • 22
  • 1
    Check out my suggestion at http://stackoverflow.com/questions/39931983/angularjs-possible-unhandled-rejection-when-using-ui-router/40366492#40366492 – Artem K. Jan 27 '17 at 00:50

2 Answers2

2

The solution is to resolve the promise with false if you want to stay in the current state or true if you want to navigate to the new state.

return $q.resolve(false);
Abhijeet Ahuja
  • 5,596
  • 5
  • 42
  • 50
1

I recommend using uiCanExit() on your controller

app.component('myComponent', {
  template: '<input ng-model="$ctrl.data" type="text">',
  bindings: { 'data': '<' },
  controller: function() {

    this.originalData = angular.copy(this.data);

    this.uiCanExit = function() {
      if (!angular.equals(this.data, this.originalData) {
        // Note: This could also return a Promise and request async
        // confirmation using something like ui-bootstrap $modal
        return window.confirm("Data has changed.  Exit anyway and lose changes?");
      }
    }
  }

This can also handle asynchronous code (return a promise).

Chris T
  • 8,186
  • 2
  • 29
  • 39