1

please, I actually have an app.module that loads the core module via lazy loading. And I load the roles in the core component to the store. Then I have a role guard that goes into the store to look at those roles. When I load some /home page and then go to the page where I have the role guard applied, everything is ok because the roles are already loaded. However, when I type the url into the browser directly to the one that the role guard is applied to, it fuckups. It loads the app.module, but then it doesn't load the core.module anymore, it loads the guard. Where aren't the roles, and even when I tried it through a skipWhile like that, it still didn't work. Any idea what to do about it? Thanks a lot

AppRoutingModule

  {
    path: '',
    children: [{
      path: '', loadChildren: () => import('./core/core.module').then(m => m.CoreModule)
    }]
  },

CoreRoutingModule

{
    path: '',
    component: CoreComponent,
    children: [
      {
        path: "test,
        loadChildren: () => import('@modules/test/test.module').then(m => m.TestModule),
        canActivate: [MyGuard]
    ......

CoreComponent

  ngOnInit(): void {
    this.authFacade.initAll();
    this.authFacade.loginCheck();
  }  

AuthGuard - only for test

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {
    return this.authFacade.user$.pipe(
      skipWhile(user => user === undefined),
      take(1),
      map(user => {
        console.log(user);
        if (!user)
          return false;

        return true;
      })
    )
  }
pietro
  • 143
  • 1
  • 9

1 Answers1

0

This may be because the roles are being loaded asynchronously in your CoreComponent and the guard is being evaluated before the roles are fetched and stored.

You can try this:

//CoreComponnet
ngOnInit(): void {
  this.authFacade.initAll();
  this.authFacade.loginCheck();

  this.authFacade.rolesLoaded$.pipe(
// wait until roles are loaded
    filter(loaded => loaded), 
// only happens once
take(1) 
  ).subscribe(() => {
    // roles loaded
  });
}

and

//AuthGuard
canActivate(
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
): Observable<boolean> {
  return combineLatest([
    this.authFacade.user$,
 // something to track roles loading
    this.authFacade.rolesLoaded$
  ]).pipe(
    skipWhile(([user, rolesLoaded]) => user === undefined || !rolesLoaded),
    take(1),
    map(([user, rolesLoaded]) => {
      if (!user) {
        return false;
      }

      // check user's roles against necesary roles for the route
      // add logic here to see if the user has the required roles

      return true;
    })
  );
}

Micah
  • 479
  • 1
  • 7
  • 17
  • 1
    The problem is that CoreComponent does not start at all. I put the console.log into appcomp and corecomp and it doesn't get into that at all – pietro Aug 10 '23 at 05:33
  • Maybe give some more info so we can figure out how to trigger that CoreComponent so it can initialize. – Micah Aug 10 '23 at 19:38