1

サーバーからユーザーを取得する Observable を作成しており、一意のユーザーのみを取得してキャッシュすることでパフォーマンスを改善しようとしています。また、すべてのユーザーが返されたら、 forkjoin を使用してユーザーの配列を更新しています。

まず、サービス呼び出しを使用してサーバーからユーザーを取得しています。

getUsersById(user_ids: number[]): Observable<User[]> {
  return Observable.forkJoin(user_ids.map(x => this.getUserById(x)));
}

これは、オブジェクトがキャッシュに存在するか、サーバーから取得する必要があるかに応じて、オブジェクトのオブザーバブルを返す次の関数を使用します。

public getUserById(user_id: number): Observable<User> {
  let tmpUser = this.users.find(x => x.id == user_id);
  if (tmpUser != null) {
    return Observable.of(tmpUser);
  } else {
    // Get Token From Cognito Session
    return this.cognito.getIdToken()
      .flatMap(token => {
      // Convert token into Header and retrieve from server
      let headers = this.getAuthHeader(token);
      return this.http
        .get(`${this.userURL}/${user_id}`, {headers: headers})
        .map((response) => response.json())
        .map(result => {
          let newUser = new User();
          newUser.deserialize(result);
          this.users.push(newUser);
          return newUser;
          });
      });
   }
}

サービスを呼び出すコンポーネントのコードは次のとおりです。

ngOnChanges() {
  if(this.reports.length != 0) {
    // Get users for reports
    let users = this.reports.map(
      x => {
        return x.user_id;
      });
    // Get unique users
    let uniqueUsers = users.filter(function (item, i, ar) {
      return ar.indexOf(item) === i;
    });
    // Make call (ForkJoin) and wait for all to return
    this.userService.getUsersById(uniqueUsers).subscribe(
      users => {
        // Add users to user array
        this.users = this.reports.map(report => {
          return users.find(user => user.id === report.user_id);
        });
        this.reportsUpdate.emit(this.reports);
      }, err => {
        console.log(err);
      });
  }
}

私が抱えている問題は、getUserById 呼び出しが完了して値を返すことを確認できるにもかかわらず、ForkJoin が返されないことです。私はかなり困惑しており、違いが完全にはわかりませんが、switchmap と flatmap の両方を試しました。

** 編集 **

getIdToken のコードは以下のとおりです

public getIdToken(): Observable<string> {
  return Observable.create(
    (observer: Observer<string>) => {
      let cognitoUser = this.getCurrentUser();
      if (cognitoUser != null) {
        cognitoUser.getSession((err, session) => {
          if (err) {
            console.log(err);
            observer.error(err);
          } else {
            if (session.isValid()) {
              observer.next(session.getIdToken().getJwtToken());
            }
          }
        });
      } else {
        observer.error('Failed To Retrieve Id Token');
      }
    });
};

getCurrentUser() {
  return this.getUserPool().getCurrentUser();
}

プログラムが次の行にヒットすることを確認しました。

observer.next(session.getIdToken().getJwtToken());

したがって、オブザーバーが完了していないことが問題であるようには見えません

4

1 に答える 1