Search code examples
angularngrxngrx-store

routes of lazy loaded modules completely re-loads the app


i have my routes setup like this.

const routes: Routes = [
{
path: '',
redirectTo: '/',
pathMatch: 'full'
},
{
path: 'bank-manager',
loadChildren: () => import('./bank-manager/bank-manager.module').then(m => m.BankManagerModule),
canActivate: [AuthGuard]
},
 {
path: 'account-holder',
loadChildren: () => import('./account-holder/account-holder.module').then(m => 
 m.AccountHolderModule),
canActivate: [AuthGuard]
   },
    {
   path: '**',
   redirectTo: ''
 }
 ];

i have a login button that is attached to an ngrx store and store is working fine. when i login a required values are set in the store. and i want that user should not be able to go to a child route if they are not logged in. so i have an authGuard set up like this

    @Injectable()
export class AuthGuard implements CanActivate {
constructor(private store: Store<AppState>, private router: Router) {}

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
): Observable<boolean> {
    return this.store.pipe(
    select(isLoggedInSelector),
    tap((loggedIn) => {
        if (!loggedIn) {
            this.router.navigateByUrl('/');
        }
    })
    );
}
}

so i go to localhost:4200 and then i click login this changes the store as required. but when i manually goto localhost:4200/account-holder it reloads the entire app and store values are lost.

what am i doing wrong here ?


Solution

  • try to return true / false in all cases.

    @Injectable({
        providedIn: 'root',
    })
    export class AuthGuard implements CanActivate {
        constructor(
            protected readonly router: Router,
            protected readonly store: Store,
        ) {}
    
        public canActivate(): Observable<boolean> {
            return this.store.pipe(
                select(isLoggedInSelector),
                distinctUntilChanged(),
                switchMap(flag => {
                    if (flag) {
                        return of(flag);
                    }
                    return from(this.router.navigate(['/'])).pipe(mapTo(false));
                }),
            );
        }
    }
    

    if you mean manually - you put the url in your browser and open a fresh copy of your angular app - it won't work. The store keeps data in memory and you need a side solution to make it persistent, for example you can use ngrx-store-localstorage, then every time you open the app it will restore store from local storage.