Reputation: 9354
I want to prevent a component from loading until API call is successful. The API calls return 200 or 401 unauthorized. Redirect user to login page if it returns 401.
I have Resolver Service:
@Injectable()
export class UserDetailResolve implements Resolve<any> {
constructor(private router: Router, private userService: UserService) {
}
resolve() {
return this.userService.verifyUserSession().catch(() => {
this.router.navigate(['auth/sign-in']);
return Observable.empty();
});
}
}
Using the resolver for route:
{
path: '',
resolve: {
valid: UserDetailResolve,
},
loadChildren: 'app/dashboard/dashboard.module#DashboardModule',
},
If user logins and refresh it works until API returns 200 but breaks (white page with no console error) if user refresh browser and API returns 401.
Edited: I also used canActivate:
canActivate() {
return this.authService.isAuthenticated()
.pipe(
tap(authenticated => {
if (!authenticated) {
this.router.navigate(['auth/sign-in']);
} else {
this.userService.verifyUserSession().toPromise().then(res => {
}).catch(error => {
this.router.navigate(['auth/sign-in']);
});
}
}),
);
}
verifyUserSession() {
return this.http.get<any>(API_URL + 'auth/verify-session');
}
But I get the same result. It displays the component for a glance as it's loaded once and when user refresh, the API returns 401 (session expired) which result in displaying component for a second and then logout.
Upvotes: 0
Views: 880
Reputation: 1164
Could you please try this code?
canActivate() {
return this.authService.isAuthenticated()
.pipe(
mergeMap(authenticated => {
if (!authenticated) {
return throwError('not authenticated');
}
return this.userService.verifyUserSession().pipe(
mapTo(true)
);
}),
catchError(error => {
this.router.navigate(['auth/sign-in']);
return of(false);
})
);
}
Upvotes: 1