Maihan Nijat
Maihan Nijat

Reputation: 9354

Angular resolver breaks the page while waiting for API call

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

Answers (1)

Leandro Lima
Leandro Lima

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

Related Questions