Trying to get the following AuthGuard to properly redirect if a user is not logged in.
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
return authService.currentUser$.pipe(map((auth: User | null) => {
console.log(auth);
if(auth !== null){
console.log(auth);
return true;
}
return router.createUrlTree(['/login']);
}));
};
and in my AuthService file I utilize the following
private currentUserSource = new ReplaySubject<User | null>(1);
currentUser$ = this.currentUserSource.asObservable();
In my app.routes.ts file my Test component is being lazy loaded.
{path: 'test', loadComponent: () => import('./test/test.component').then(mod => mod.TestComponent), canActivate: [authGuard]},
Instead of redirecting the user to a login page, it just shows a blank page.
Thanks
I have re-written it several times utilizing different methods, but they all failed at redirecting.
What I think the problem may be is using a ReplaySubject for your currentUserSource variable, I would advice replacing it for a BehaviourSubject :
private currentUserSource = new BehaviourSubject<User | null>(null);
currentUser$ = this.currentUserSource.asObservable();
As to why I believe this might be the source of the problem, a guard that causes a lock on an empty page usually means that its waiting for an Observable to emit a value.
A ReplaySubject holds no default value meaning that if no value was emitted before the guard is called, your authGuard will subscribe to an observable that will will never emit any value, which causes it to wait indefinitely.
Changing it to a BehaviourSubject will ensure that there is always a value, so the guard may always be able to complete.
I tried to replicate your issue on stackblitz, and when using functional guards, I was running into the "no provider for authguard", in which would return a black page.
So I turned the functional authguard into a class guard, and provided in root
See here:
https://stackblitz.com/edit/angular-standalone-route-fhto46?file=src%2Froutes%2Froutes.ts
@Injectable({ providedIn: 'root' })
class AuthGuardClass implements CanActivate {
private router = inject(Router);
canActivate() {
return of({ user: 'mock' }).pipe( // Replace mock
map((auth: { user: string } | null) => {
console.log(auth);
if (auth !== null) {
console.log(auth);
return true;
}
return this.router.createUrlTree(['/login']);
})
);
}
}
export const routes: Routes = [
{
path: '',
canActivate: [AuthGuardClass],
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'home',
},
{
path: 'home',
loadComponent: () =>
import('./home.component').then((mod) => mod.HomeComponent),
},
],
},
{
path: 'login',
loadComponent: () =>
import('./login.component').then((mod) => mod.LoginComponent),
},
];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With