Search code examples
angularangular-routerangular-router-guardsangular-guards

angular2: call canDeactivate for same route and component but different parameters


In my application, there are multiple links with the same route but with different queryParams and fragment.

for example, I have links like:

.../pages/golestan/npform?fid=26270#26270
.../pages/golestan/npform?fid=26280#26280
.../pages/golestan/npform?fid=26290#26290

When I am in one of the above routes and navigate to same route by different params , the route is not changing, but by change RouteReuseStrategy this problem was solved. Now I want to call canDeactivate for changing route, canDeactivate was called when I navigate to other routes but when I navigate to this same route by different queryParams and fragment, canDeactivate is not called!

const routes: Routes = [{
    ...
    {
      path: 'npform',
      component: NpFormComponent,
      canDeactivate: [
        NpFormGuard
      ],
    },
   ...
}];

@NgModule({
  declarations: [
    NpFormComponent
  ], 
  imports: [ ...
    RouterModule.forChild(routes)
  ],
  providers: [
    NpFormGuard
  ]
})
export class GolestanModule { }

@Injectable({providedIn: 'root'})
export class NpFormGuard implements CanDeactivate<KoFormComponent> {
  canDeactivate(
    component: NpFormComponent, 
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree 
  {
    return !component.webBusy;
  }
}

import { Router } from '@angular/router';
constructor(private router: Router) {
    this.router.routeReuseStrategy.shouldReuseRoute = (future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot) => {
        const defaultReuse = (future.routeConfig === current.routeConfig);
        if(future.routeConfig&&future.routeConfig.path=='npform'&&
             (future.queryParams.fid||current.queryParams.fid)&&(future.queryParams.fid!=current.queryParams.fid))
            return false;
        return defaultReuse;
    
    };
}

Solution

  • My problem is solved by use RunGuardsAndResolvers paramater and set it to 'always'. this configuration run guard everytime.

    const routes: Routes = [{
        ...
        {
          path: 'npform',
          component: NpFormComponent,
          runGuardsAndResolvers: 'always',
          canDeactivate: [
            NpFormGuard
          ],
        },
       ...
    }];
    

    see https://angular.io/api/router/RunGuardsAndResolvers