Search code examples
angularangular7angular-router-guardsangular-guardscandeactivate

CanDeactivate guards does not runs as expected, after pressing browser back button


I have implemented canDeactive guard, once browser button is clicked it popups a Model and ask Yes/No. After clicking on No it stays on the same page and Again if i press the back button the popup appears and after clicking No/Yes button it redirects to the blank page url from the browser history instead of staying on the same url.

Please find the code for deactivate guard.

import { Injectable, HostListener, } from '@angular/core';
import { CanDeactivate, ActivatedRoute, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
:
:
:
:

export abstract class myCompCanDeactivate {

  abstract  canDeactivate(): boolean;

    @HostListener('window:beforeunload', ['$event'])
    unloadNotification($event: any) {
        if (!this.canDeactivate()) {
            $event.returnValue = true;
        }
    }
}

@Injectable()

export class DeactivateGuardService implements CanDeactivate<myCompCanDeactivate> {
  showDashboard:boolean=false;
  islogout:any;
  sStep:number;
  demoLastSection:number = 0;
  menuitem:SitefinityPortalMenu;

  constructor(private next:ActivatedRoute,private resourceService: ResourceService,
    private matDialog: MatDialog,private browserGlobalService: BrowserGlobalService, private route:Router ){}
  async canDeactivate(component: myCompCanDeactivate,currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Promise<boolean> {

    if(!component.canDeactivate()){

      if (this.browserGlobalService.GlobalLogout=== 'logout') {
          this.browserGlobalService.GlobalLogout = '';
          return true;
        }

      //Get Portal left menus from sitefinity.
      this.menuitem = await this.resourceService.getPortalMenus("Portal_Left_Menu").toPromise();


      var str:SitefinityMenuItem[] = this.menuitem.MenuItems.filter((m)=>{return m.LinkUrl.includes(nextState.url) && m.Hidden===false});

      if ( nextState.url!='/demoSite' && nextState.url === (str.length>0?str[0].LinkUrl:'') ){return true; }

      this.sStep = SaleSteps.Review;
      this.demoLastSection = PSSections.signStep;


      if (this.browserGlobalService.PLSavedSection !=  this.demoLastSection || this.browserGlobalService.PLSavedSection != this.sStep ){
      let modalData = new ModalData();
      modalData.Header = this.resourceService.getViewLabel("ModalHeader_BrowserBack"); 
      modalData.Body = this.resourceService.getViewLabel("ModalBody_BrowserMessage"); 
      modalData.ControlArray = [
        new ButtonAction(this.resourceService.getViewLabel("ModalCancel_Yes"), "YES"),
        new ButtonAction(this.resourceService.getViewLabel("ModalCancel_No"), "NO")
      ];
          let dialogRef = this.matDialog.open(GspModalComponent, {
              data:  modalData
          });
          dialogRef.afterClosed().subscribe(result => {
               if (result && result.toLowerCase() === "yes") {
                  this.browserGlobalService.callComponentMethod("");
                  // this.route.navigated = true;
                  return false;
                }
                return false;
          });
        }
    }
    return false;
  }
}

Solution

  • I found a solution to this issue. Solution : history.pushState("","","/sales"); (just pushed router state in the browser history) As the url always remains the same in my case so whenever browser back button was press, the browsers default activity was performed. so it popout the state from history and it reaches to the last history state after that the browser navigates to the blank page.