event.preventDefault() not working for routeChangeStart in angularjs app

19,926

Solution 1

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

Solution 2

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.

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

Solution 4

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

Share:
19,926
iJade
Author by

iJade

JavaScript enthusiast

Updated on June 05, 2022

Comments

  • iJade
    iJade about 2 years

    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

    • F Lekschas
      F Lekschas over 11 years
    • iJade
      iJade over 11 years
      @Flek but that solution wont prompt the user for a confirmation instead simply wont allow the browse back button to work
    • Sam
      Sam about 11 years
      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 ?
    • iJade
      iJade about 11 years
      @Sam plz check this stackoverflow.com/questions/14849857/… Not exact soln but may help
  • iJade
    iJade over 11 years
    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
  • F Lekschas
    F Lekschas over 11 years
    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.
  • iJade
    iJade over 11 years
    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.
  • F Lekschas
    F Lekschas over 11 years
    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?
  • Mustafa Bereket
    Mustafa Bereket almost 6 years
    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?