angular: fix(router): canDeactivate should not change the url when returns false and skipLocationChange has been set to true

I’m submitting a … (check one with “x”)

[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior This is leftover from : https://github.com/angular/angular/issues/10321

With the following routes:

path: 'view',
children: [
    {

        path: ':id',
        component: CustomerViewComponent,
        resolve: {
            customerViewData: CustomerResolve,
        },
        canDeactivate: [CanDeactivateGuard],
        children: [
            {
                path: 'edit',
            },
            {
                path: ''
            }
        ]
    }
]

If you navigate to a route like this using skipLocationChange:

this.router.navigate(['edit'], { relativeTo: this.route, skipLocationChange: true });

Then when you are about to navigate away and return false in canDeactivate(), the /edit creeps in the URL.

Expected behavior The URL should not change to /edit

Minimal reproduction of the problem with instructions

http://plnkr.co/edit/K1JnuZfQ5S0WHnWmp6Zv?p=preview

Steps:

  • pop out the preview window to see the address bar
  • click on a crisis center
  • click on “Dragon burning cities”
  • The URL stays /crisis-center because of skipLocationChange
  • and edit the text
  • use the browser back commands to go back.

ACTUAL:
The URL goes to /crisis-center/1

EXPECTED:
The URL should stay to /crisis-center

What is the motivation / use case for changing the behavior? This causes further problem when using relative routing such as …/…

Please tell us about your environment: Visual Studio 2015, IIS Express, npm@3.10.5

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 5
  • Comments: 16 (2 by maintainers)

Commits related to this issue

Most upvoted comments

As I see, still not fixed in 4.2.4 😦

came across similar problem, a simple working around I have used

canActivate(route, state) {
  /* problem is with history */
   if(activate == false) 
      this.platformLocation.pushState('state', 'msg', previousVisitedRoute);
   return activate;
}

any update or workaround for this?

Actually this is resolved by the canceledNavigationResolution: 'computed' option which was added to fix #13586. This will be available in v13:

https://stackblitz.com/edit/angular-ivy-rqt2v8?file=src%2Fapp%2Fapp.component.ts

If we navigate to a child component using this.router.navigate([‘edit’], { relativeTo: this.route, skipLocationChange: true }); and CanDeactivateGuard returns false, the URL shows up.