Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Ability to cancel $routeChangeStart event #5581

Description

@yentheo

Hi, I have an issue which seems to occur more often in the community.
It's the same as #592 and multiple stackoverflow posts (http://stackoverflow.com/questions/14895016 - http://stackoverflow.com/questions/16344223 etc)
Some of these issues were resolved by using locationChangeStart.

It would work too for me, if not for the next problem.

I'm making an app with some standard pages like a home-page and a contact-page. Then we have some kind of wizard. The routes look like this.

$routeProvider.
    when('/home', { controller: 'homeController', templateUrl: '/home.html'}).
    when('/contact', { controller: 'contactController', templateUrl: '/contact.html'}).
    when('/wizardPage1', { controller: 'wizardPageOneController', templateUrl: '/wizardPage1.html', wizard: true}).
    when('/wizardPage2', { controller: 'wizardPageTwoController', templateUrl: '/wizardPage2.html', wizard: true}).
    when('/wizardPageSave', { controller: 'wizardPageSaveController', templateUrl: '/wizardPageSave.html', wizard: true}).
    otherwise({ redirectTo: '/home' });

Now I can complete the wizard and save on the WizardSavePage. But what I want is when I'm on WizardPage2 and I navigate to home or contact, I want to show a confirmation "You have unsaved changes. Do you want to continue" or something.

The easiest code would be:

$rootScope.$on("$routeChangeStart", function (event, next, current) {
    if (!wizardService.saved && current.wizard && !next.wizard) {
        if (!confirm("You have unsaved changes. Do you want to continue?")) {
            event.preventDefault();
        }
    }
});

But this does not work, obviously. I could do this with locationChangeStart but then I lose all the route data.

What would be the best way to make something like this?

Thanks in advance!

Activity

  1. IgorMinar commented on Jan 3, 2014

    @IgorMinar
    Contributor

    This is not ideal, but you could just listen on $routeChangeStart and keep references to current and next route. Then when the $locationChangeStart event is broadcasted you can use the kept references to determine if you want to abort or not.

    $routeChangeStart always fires before $locationChangeStart.

  2. yentheo commented on Jan 3, 2014

    @yentheo
    Author

    You suggest something like this:

    var currentRoute, nextRoute;
    
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        currentRoute = current.$$route;
        nextRoute = next.$$route;
    });
    
    $rootScope.$on("$locationChangeStart", function (event, next, current) {
        if (!wizardService.saved && currentRoute.wizard && !nextRoute.wizard) {
            if (!confirm("You have unsaved changes. Do you want to continue?")) {
                event.preventDefault();
            }
        }
    });
    

    I thought there may be some functionality on the routeProvider to get the route data based on a url. Something like:

    var routeData = $routeProvider.getRoute('/someUrl/5');
    

    Thanks for your answer, btw.

  3. yentheo commented on Jan 3, 2014

    @yentheo
    Author

    I have just given this a try... It did not work. $locationChangeStart fires before $routeChangeStart.
    I should add that I don't use $location.path to navigate but I always use hyperlinks.

    Maybe that changes something in the order?

  4. khellang commented on Jan 7, 2014

    @khellang
    Contributor

    👍 For the proposed fix. Too bad I can't use it right away 😄

  5. added a commit that references this issue on Jan 9, 2014
    73c665e
  6. caitp commented on Jan 9, 2014

    @caitp
    Contributor

    I was bored and decided to push a clean patch for this @yoerlemans --- but if you reopen a PR I'll take a look at it and close mine.

  7. added 4 commits that reference this issue on Jan 9, 2014
    b3b46fb
    f42449d
    2317794
    6291a4f
  8. jakubsikora commented on Jan 21, 2014

    @jakubsikora

    @IgorMinar, @yoerlemans so... any other alternative for this? How can I stop the change after the next route has been parsed? As the parseRoute API is not exposed, is my only alternative to copy that code into my app and parse the paths in $locationChangeStart by myself? I need the route definition for checking things like permissions.

  9. sinelaw commented on Jan 27, 2014

    @sinelaw
    Contributor

    +1

  10. khellang commented on Jan 27, 2014

    @khellang
    Contributor

    For anyone who wants to reject a route change (e.g. for authentication/authorization purposes), as a workaround for this issue, check out this plnkr.

  11. mikehayesuk commented on Apr 5, 2014

    @mikehayesuk

    +1 👍

  12. romul commented on Apr 11, 2014

    @romul

    +1 for the proposed fix.

  13. etorres commented on Apr 19, 2014

    @etorres

    +1 clean and nice solution

  14. jamesmorgan commented on May 8, 2014

    @jamesmorgan

    +1 👍

  15. geddski commented on May 22, 2014

    @geddski
    Contributor

    #4192 will solve this.

  16. guptapriyank commented on Jun 10, 2014

    @guptapriyank

    +1 helped me too

  17. swlasse commented on Jun 10, 2014

    @swlasse

    Thanks for the workaround. Are there any plans for when the fix for this issue will be available in one of the stable builds?

  18. pencilcheck commented on Aug 10, 2014

    @pencilcheck

    @khellang's solution works for me. Thanks.

  19. OakBehringer commented on Aug 15, 2014

    @OakBehringer

    Building on the example provided by @khellang , here is an demo of how you can pass rights/roles to the route provider.

    http://embed.plnkr.co/gfF8c0ggklNh9F1c71sF/preview

  20. added 2 commits that reference this issue on Oct 3, 2014
    80ed319
    5491431
  21. added a commit that references this issue on Oct 8, 2014
    46f36e1
  22. added a commit that references this issue on Oct 9, 2014
    0ea3b9b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions