Robin Thoni
Robin Thoni

Reputation: 1721

How to prevent state change in AngularJS 1.6 with ui-router 1.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...

Upvotes: 0

Views: 1512

Answers (2)

Abhijeet Ahuja
Abhijeet Ahuja

Reputation: 5950

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);

Upvotes: 2

Chris T
Chris T

Reputation: 8216

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).

Upvotes: 1

Related Questions