1
votes

I have a problem that when I logout and navigate to /, canActivateChild guards are not executed to redirect to login.

My requirement is that none of the app is accessible without login.

Here is my root Route config:

const appRoutes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: '/dashboard',
  },
  {
    path: 'login',
    component: LoginComponent
  },
  {
    path: '',
    runGuardsAndResolvers: 'always',
    children: [
      { path: 'dashboard', component: DashboardComponent },

    ],
    canActivateChild: [AuthGuard],

  }
  // { path: '**', component: PageNotFoundComponent }
];

Here is my AuthGuard (userState) is called from canActivateChild

private userState(nextRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree> {
  return this.auth.authState.pipe(
    first(),
    map(user => {
      if (user != null) {
        return true;
      } else {
        const url = this.router.parseUrl('/login');
        console.log('redirect url', state.url);
        url.queryParams['redirect'] = state.url;
        return url;
      }
    }),
  );
}

On login, I navigate to either / or redirect queryParam, if it exists. On logout, I navigate to /, the idea is that it will redirect to dashboard, and, since dashboard is protected and user is null, go to /login?redirect=dashboard.

Everything works, except the last part. When I logout, it redirects to dashboard but DOES NOT activate the canActivateChild guard, completing the redirect to dashboard with success. If I replace canActivateChild with canActivate, it works as desired.

More details:

2
could you provide the code of your AuthGuard service ? - Bernard Pagoaga
it's there: the second code block - f.khantsis

2 Answers

0
votes

I don't think you need to use canActivateChild with this. You just need to use canActivate at the top level and that will take care of any children of that route.

E.G:

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },
    {
        path: 'dashboard',
        canActivate: [AuthGuard],
        children: [
            { path: '', redirectTo: 'overview', pathMatch: 'full' },
            { path: 'overview', component: DashboardComponent }
            // More child routes go here
        }
    }
];

Hope this helps!

-1
votes

You declare the '' path twice. Perhaps its being caught in the first declaration. I'd suggest you moved the first declaration into the second like so. { path: '', runGuardsAndResolvers: 'always', children: [ { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, { path: 'dashboard', component: DashboardComponent }, ], canActivateChild: [AuthGuard], }