Router CanDeactivate runs twice when back button is pressed

See original GitHub issue

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

[x] bug report => search github for a similar issue or PR before submitting

Current behavior CanDeactivate guard runs twice if i use browser back button and canDeactivate returns promise or observable (any delayed result). If i return true/false it will execute once. If i use links to navigate it also work fine. The problem is that i can’t create plunker 😦 Relevant logs:

RouterEvent(type='routeStart', id='3', url=/dashboard/master/department/list)
RouterEvent(type='routeRecognize', id='3', url=undefined, urlAfterRedirects=/dashboard/master/department/list, state=Route(url:'', path:'') { Route(url:'dashboard', path:'dashboard') { Route(url:'master/department/list', path:'master/department/list') }  } )
canDeactivatePageDetailsComponent1.canDeactivate
RouterEvent(type='routeStart', id='4', url=/dashboard/master/department/list)
RouterEvent(type='routeRecognize', id='4', url=undefined, urlAfterRedirects=/dashboard/master/department/list, state=Route(url:'', path:'') { Route(url:'dashboard', path:'dashboard') { Route(url:'master/department/list', path:'master/department/list') }  } )
canDeactivatePageDetailsComponent1.canDeactivate
RouterEvent(type='routeCancel', id='3', url=/dashboard/master/department/list)
RouterEvent(type='routeEnd', id='4', url=/dashboard/master/department/list, urlAfterRedirects=/dashboard/master/department/list)
RouterEvent(type='routeSuccess', id='4', url=/dashboard/master/department/list, urlAfterRedirects=/dashboard/master/department/list)

It looks like navigation was fired twice.

Expected behavior Should be executed once and wait for result.

Reproduction of the problem

public canDeactivate(component:any, route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|Promise<boolean>|boolean
    {
        console.trace('canDeactivate?');
        return new Promise<boolean>((resolve)=>{
            setTimeout(()=>{
                resolve(true);
            }, 1000);
        });
    }

What is the motivation / use case for changing the behavior? It results in two confirm dialogs. I would really appreciate solution to this.

  • Angular version: 2.0.0-final
  • Browser: [all]
  • Language: [TypeScript 1.8]

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:7
  • Comments:7

github_iconTop GitHub Comments

1reaction
kemskycommented, Oct 2, 2016

If anybody needs workaround follow this steps:

  1. Use rxjs share operator to reuse created observables.
  2. Create map in your guard RouterStateSnapshot.url->observable<boolean> and save created observables to this map.
  3. Add cleanup code to remove url from the map when observable completes (operators finally or do).
0reactions
angular-automatic-lock-bot[bot]commented, Sep 14, 2019

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular 4 canDeactivate fails if back button is hit twice in a row
As a workaround, you can manually put the active url back to the history: ... if(!confirmation) { const currentUrlTree = this.router.
Read more >
strange issue with canDeactivate guard : r/Angular2 - Reddit
I have a canDeactivate guard that throws a modal confirmation dialog ... to click Yes twice before the guard passes the check and...
Read more >
angular candeactivate back button
Angular canDeactivate fails if the back button is hit twice in a row #33956. ... on the NavigationStart event emitted by the Router...
Read more >
CanDeactivate - Angular
Interface that a class can implement to be a guard deciding if a route can be deactivated. If all guards return true ,...
Read more >
How to use a custom dialogue with the canDeactivate route ...
Then the navigation will either execute or abort. Now, let's implement the interface in our component: For now we can let the function...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found