Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router CanDeactivate runs twice when back button is pressed #11754

Closed
kemsky opened this issue Sep 20, 2016 · 7 comments
Closed

Router CanDeactivate runs twice when back button is pressed #11754

kemsky opened this issue Sep 20, 2016 · 7 comments

Comments

@kemsky
Copy link

kemsky commented Sep 20, 2016

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]
@ErikGrijzen
Copy link

Having the exact same issue for the CanActivate guards. Manually changing the url or pressing back/forward browser history buttons is triggering the guard twice. I'm using the LocationHashStrategy.

@kemsky
Copy link
Author

kemsky commented 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).

@vsavkin vsavkin self-assigned this Oct 25, 2016
vsavkin added a commit to vsavkin/angular that referenced this issue Oct 28, 2016
vsavkin added a commit to vsavkin/angular that referenced this issue Oct 28, 2016
vsavkin added a commit to vsavkin/angular that referenced this issue Oct 28, 2016
@TetianaP
Copy link

@ErikGrijzen I have the same problem. It is already fixed for you?

@phacic
Copy link

phacic commented Jun 28, 2017

Had the same problem and realized it was because i was return a promise. I changed it to an observable and it was fixed...

@varkq01
Copy link

varkq01 commented Aug 29, 2018

I have similiar issue, but CanDeactivate is called twice when I am using links (second modal appear after closing first one). When I use router.navigate method canDeactivate it's called only once.

Returning observable instead of promise does not fix it.

Does anybody have workaround for that?

my canDeactivate method:

canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (this.checkIfChangesHaveBeenMade()) {
      const confirmation= this.mS.open(confirmationTmpl);

      return from(confirmation.result.then((result) => {
        return result === 'Ok';
      }, (reason) => {
        return false;
      }));
    }
    return true;
  }

I am using Angular Router 6.1.4

@kemsky Could you provide us your workaround. I don't understand your explanation. Thanks.

@kimkong88
Copy link

I have similiar issue, but CanDeactivate is called twice when I am using links (second modal appear after closing first one). When I use router.navigate method canDeactivate it's called only once.

Returning observable instead of promise does not fix it.

Does anybody have workaround for that?

my canDeactivate method:

canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (this.checkIfChangesHaveBeenMade()) {
      const confirmation= this.mS.open(confirmationTmpl);

      return from(confirmation.result.then((result) => {
        return result === 'Ok';
      }, (reason) => {
        return false;
      }));
    }
    return true;
  }

I am using Angular Router 6.1.4

@kemsky Could you provide us your workaround. I don't understand your explanation. Thanks.

I am having the same issue, were you able to resolve this?

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants