Have an auth service which fetches data immediately after auth:
export class AuthService {
profile: BehaviorSubject<Profile| undefined> = new BehaviorSubject<Profile| undefined>(undefined);
constructor(private auth: Auth, private http: HttpHandlerService) {
//login and fetch profile data
this.auth.isAuth.subscribe(isAuth => {
if (isAuth) {
this.http.getProfile.subscribe(profile => this.profile.next(profile))
}
});
}
}
The profile data is required globally in the app (in the header, etc.).
Problem: On a page refresh/page reload, my Guard does not wait for the Authsevice to finish, hence I cannot access my profile data within the guard.
The only feasable solution seems to be to move the data fetching logic into the Guard, see AuthGuard doesn't wait for authentication to finish before checking user
However, this is not sufficient in my case. I need my profile data globally, it shall not only be fetched if I'm on a guarded route.
So all I want to do is to ensure that my data is fetched before the guard does his work.
My current solution:
export class ProfileGuard {
constructor(private auth: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.auth.profile.pipe(
skipWhile(profile => !profile),
tap(profile=> {
if (profile && profile.banned) {
this.router.navigate(['/banned']).then();
}
}),
take(1),
map(() => true)
);
}
I have two problems with this: 1) I need to add this additional logic to ALL my guards! 2) This solution feels quite hacky.
Is there really no simpler/better way to check my profile data within a Guard right after refresh/page load?