CanActivateで取得したデータをResolveで返したい

次に遷移するコンポーネントの表示に必要なデータを、Resolveを使ってサーバーから取得するわけです。
しかし、サーバーでしかできない入力チェックとか、あるわけです。
なのでCanActivateでサーバーにアクセスするんですが、それならその時にデータも一緒に取ってきてResolveで返したいわけです。
ところが、こいつらの実行順はCanActivate→Resolveなわけです。
そしてcanActivate()の引数であるActivatedRouteSnapshotも、RouterStateSnapshotもResolveにデータを受け渡すような機能を持っていないのです。
CanActivateで適当なServiceにデータを保存して、Resolveでそれを返せばできますが・・・あまりスマートでない。


というわけで悩んだんですが、よく考えたら1個のクラスでCanActivateもResolveも実装してしまえばいいですね。単純。

@Injectable()
export class SomeComponentGuard implements CanActivate, Resolve<Data> {

  private data: Data;
  
  constructor(
    private service: ServerAccessService
  ) { }
  
  canActivate(
      next: ActivatedRouteSnapshot,
      state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.service.getData(next.queryParams).map(
      data => {
        this.data = data;
        return true;
      }
    ).catch(e => {
      return Observable.of(false);
    });
  }
  
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Data | Observable<Data> | Promise<Data> {
    return data;
  }

}