15

Hope any angularjs gurus can help me with this.Here is my angularjs code

$scope.$on('$routeChangeStart', function(event, next, current) {
                if ($scope.myForm.$dirty) {
                    if(!confirm("Unsaved, do u want to continue?")) {
                        event.preventDefault();
                    }
                }
            });

It alerts in browser back button click when data is dirty, but on clicking cancel or ok it still completes the route change.Seems like event.preventDefault() is not working. Can any one point out what may be wrong

iJade
  • 23,144
  • 56
  • 154
  • 243
  • Probably check: http://stackoverflow.com/questions/14900008/prevent-redirect-behaviour-in-angularjs-app – F Lekschas Feb 15 '13 at 22:01
  • @Flek but that solution wont prompt the user for a confirmation instead simply wont allow the browse back button to work – iJade Feb 16 '13 at 06:58
  • I'm running into the same issue. I've tried both $routeChangeStart and $locationChangeStart, but none of them worked. Have you found a suitable solution to this problem ? – Sam Apr 25 '13 at 17:53
  • @Sam plz check this http://stackoverflow.com/questions/14849857/detect-unsaved-data-using-angularjs Not exact soln but may help – iJade Jun 25 '13 at 03:52

5 Answers5

33

I had lots of trouble finding this one, but instead of the "$routeChangeStart" event, you can listen to the "$locationChangeStart" event, for which you can prevent default:

$scope.$on("$locationChangeStart", function(event, next, current) {
    if (!confirm("You have unsaved changes, continue navigating to " + next + " ?")) {
        event.preventDefault();
    }
});

You could also always prevent default, store "next", and display a clean JS modal and decide asynchronously.

$locationChangeStart is currently undocumented but referenced here : https://github.com/angular/angular.js/issues/2109

Zorglub
  • 2,077
  • 1
  • 19
  • 22
  • for some reason this doesnt work for me, I copied and pasted the exact same code block you provided, but when I click cancel, it still takes me to the next page. Do you have any idea why would my preventDefault() not work? – Mustafa Bereket Aug 08 '18 at 02:07
5

Fixed exactly after Angular 1.3.7 https://code.angularjs.org/1.3.7/docs/api/ngRoute/service/$route

$routeChangeStart Broadcasted before a route change. At this point the route services starts resolving all of the dependencies needed for the route change to occur. Typically this involves fetching the view template as well as any dependencies defined in resolve route property. Once all of the dependencies are resolved $routeChangeSuccess is fired.

The route change (and the $location change that triggered it) can be prevented by calling preventDefault method of the event. See $rootScope.Scope for more details about event object.

Roy Calderon
  • 6,361
  • 3
  • 22
  • 21
3

According to the AngularJS docs (see at $broadcast) you simply cannot cancel an event of type broadcast ($routeChangeStart is of that type):

The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified. Afterwards, the event propagates to all direct and indirect scopes of the current scope and calls all registered listeners along the way. The event cannot be canceled.

F Lekschas
  • 12,481
  • 10
  • 60
  • 72
  • ok so is dere any other way to detect browser back button click other than using $routeChangeStart.I already tried locationChangeStart and onbeforeunload, both not working – iJade Feb 15 '13 at 13:34
  • I would call a function first that checks all dependencies and only if they are true you change the location. A bit more details about what you are actually trying to do would be good. – F Lekschas Feb 15 '13 at 13:52
  • well actually i have a form.If the form has unsaved data and the user clicks browser back button it asks for a confirmation message.This is what i'm actually trying to do.It would be help full if u can post some code. – iJade Feb 15 '13 at 13:54
  • As I said instead of changing the location directly when clicking the "submit" button just call a function and evaluate the form. What you are asking for now is more like how to evaluate a form rather than why does preventDefault() does not work or do I get something wrong? – F Lekschas Feb 15 '13 at 15:38
2

This problem was fixed in the newest versions ( >= 1.3.8 ).

Since the arguments supplied to $routeChangeStart are more detailed (and often more useful), if possible, try to update your angular version ...

Marcelo C.
  • 3,822
  • 2
  • 22
  • 11
0

The problem might persist if you are using a $stateProvider. In this case use:

$scope.$on('$stateChangeStart', function( event){
  .....
  event.preventDefault();
});
john
  • 1