Search code examples
spartacus-storefront

CanDeactivate in Spartacus


What we need: Display dialogs on some pages with forms when the user navigates to a different route. Is there some way in Spartacus to have a dialog pop up on the page when navigation happens and the form has values which were not sent yet?

How it can be achieved in regular Angular application: The usual way would be to use the Deactivate Guard, but in order to use deactivate guard I need to create routing in frontend and ignore the page layout provided by the Commerce office, because the Spartacus does not provide an option to add deactivate guards to components. But this would not work correctly with header and footer provided by the Commerce office.

RouterModule.forChild([
    {
        path: 'xyz',
        component: XYZComponent,
        canDeactivate: mapToCanDeactivate([XYZDeactivateGuard]),
    },
)]

What else we tried: We tried to find a solution to have the same behavior provided by deactivate guard, but I did not find any. The only partial solution is to implement 'window:beforeunload' but this only works for page refresh and not for navigating to a different page in the application.

@HostListener('window:beforeunload', ['$event'])
check($event: any) {
    if (this.formDirty) {
        $event.returnValue = 'Your data will be lost!';
    }
}

Solution

  • We can add deactivate guard if we have custom route configuration like below:

      {
    path: 'checkout/multi/add-payment-method',
    component: PageLayoutComponent,
    canDeactivate: [AbandonEgiftcardGuard],
    

    },

    Or else you can handle this without using guard like below:

      private handleCartNavigationEvents(): void {
    this.router.events.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
      if (event instanceof NavigationStart) {
        if (this.router.url.includes('/cart') && this.router.url !== event.url) {
          this.navigateToUrl = event.url;
          this.router.navigateByUrl(this.router.url);
          this.openLeaveCartConfirmModal();
        }
      }
    });
    

    }