canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { return interval(10000) .pipe( mergeMap(() => { return this.httpClient.get('/isAuthorized') .pipe( map(response => { return response.authorized; }) ); }) );トランスパイルは通りました。が、一回しか HTTP アクセスが発生しません。
デバッガで canActivate() を出たあとを追ってみたところ…
pipe(first()) \(^o^)/オワタ
https://github.com/angular/angular/blob/master/packages/router/src/pre_activation.ts#L248
private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> { const canActivate = future.routeConfig ? future.routeConfig.canActivate : null; if (!canActivate || canActivate.length === 0) return of (true); const obs = from(canActivate).pipe(map((c: any) => { const guard = this.getToken(c, future); let observable: Observable<boolean>; if (guard.canActivate) { observable = wrapIntoObservable(guard.canActivate(future, this.future)); } else { observable = wrapIntoObservable(guard(future, this.future)); } return observable.pipe(first()); })); return andObservables(obs); }timeout() の Observable を返しても最初の1回目の Observable<boolean> しか使わない、ということですね。
まあ、Guard は Route の許可をするかどうかの位置にあるものなので、一度表示した Route を拒否することは想定していない実装ということではないかと思います。
おとなしくコンポーネント内で interval() 回して画面遷移させるようにします…
そうそう、interval() の unsubscribe() も忘れずに…