0
votes

We have a canActivate guard which should return Observable(boolean).

The boolean status is obtained form service, where we need to poll 3 times with 1 sec interval until we receive response 'true'.

Problem is that whenever takeWhile returns false we receive the following

error:
failure.service.ts:36 Error: Uncaught (in promise): EmptyError: no elements in sequence
EmptyError: no elements in sequence

below is the the code that is causing the issue. RXJS is version ^6.2.1 Angular CLI is version ^6.0.8

import { repeat, delay, takeWhile, map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { Observable, of } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService) { }

  canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.isAuthenticated().pipe(
      delay(1000),
      repeat(3),
      takeWhile((authenticated: boolean) => {
        return !authenticated;
      })
    );
  }
}
1

1 Answers

0
votes

From my understanding, the EmptyError means that an observable that is supposed to emit something is completed without emitting anything. The takeWhile operator, whenever returning false, causes the observable not to emit anything, which the canActivate expects.

I think you need to use the map operator instead of takeWhile:

canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> {
return this.authService.isAuthenticated().pipe(
  delay(1000),
  repeat(3),
  map((authenticated: boolean) => {
    return !authenticated;
  })
);

}