0

I am using Angular 4.3.5. Our app has "programs" that a user can be "subscribed" to. I have a router guard function that looks like this:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const programName = route.params['program_name'];
    const programId = this.programService.getIdForName(programName);
    if (this.userService.isLoggedIn()  &&  this.subscriptionService.isSubscribed(programId)) {
      return true;
    } else {
      this.router.navigate(['']);
      return false;
    }
}

To get the program id, I need to call the server. To get the list of subscriptions for the user and determine if they are subscribed to this particular program, I need to call the server.

The server calls are asynchronous using RxJS. However, my canActivate function is constrained to return a boolean. I am unsure of how to bridge this async/sync programming gap.

In RxJava, for example, I could call toBlocking() to wait for the HTTP call to resolve. But there is no such operator in RxJS. I've tried toArray(), and take(1).toArray()[0], but nothing seems to work.

In fact, I'd like to push this async/sync bridge down lower; i.e. I want subscriptionService.isSubscribed(programId) to return a boolean instead of a Observable<boolean>, because I can cache the list of subscriptions in the SubscriptionService, so that I don't need to call the server every time; but I don't think that changes the programming challenge.

Ken DeLong
  • 929
  • 2
  • 8
  • 27

2 Answers2

0

There is no such thin as blocking in JS.

Angular can handle a returned observable

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const programName = route.params['program_name'];
    return this.programService.getIdForName(programName).map(pn => {
      if (this.userService.isLoggedIn()  &&  this.subscriptionService.isSubscribed(programId)) {
        return true;
      } else {
        this.router.navigate(['']);
        return false;
      }
   });
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

The canActivate function can return an Observable<boolean>.

jlareau
  • 2,860
  • 1
  • 17
  • 11