1
votes

I have a pending change guard like

    import {CanDeactivate} from '@angular/router';

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean | Observable<boolean>;
}

export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
    // if there are no pending changes, just allow deactivation; else confirm first
    return component.canDeactivate() ?
      true :
      // NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
      // when navigating away from your angular app, the browser will show a generic warning message
      // see http://stackoverflow.com/a/42207299/7307355
      confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
  }
}

My issue is that I also have some tab controls that are tied into the page route params, so when a tab is navigated it updates the route params and vice versa. It updated the param by navigating to the current route with the new param, which doesn't reload the component since it is the current route still. My issue is that I do not want these route changes to be considered a deactivation by the PendingChangesGuard since the component is still on the page in a different tab.

Ideally I would be able to pass some parameters to the guard telling it which route params to ignore in the case of re-navigating to the current route, and then some way to detect within the guard if the only changes are one of the ignored parameters. I'm not sure how to detect changes in the params like that, and ideas?

1
you have access to route params in canDeactivate you can use it directly to build your logic `canDeactivate(component: ComponentCanDeactivate, route: ActivatedRouteSnapshot,state: RouterStateSnapshot).Madhu Ranjan
I am aware of that, but how can I look at the previous route and the current route and figure out which parameters changed?Josh

1 Answers

1
votes

You could use query params instead of route params. Query params don't cause guards to re-run. That's not the only difference between query params and route params (or matrix params, or whatever they're called), but it makes them worth considering. The angular router is pretty opinionated so you may never find an elegant solution.

Query params:

this.router.navigate([], {
  queryParams: {'tab': whatever}
});

or

<a [routerLink]="[]" [queryParams]="{'tab': whatever}">tab</a>