2017-03-10 8 views
0

私のコードでは、MS Graphからユーザーリストを取得していますが、これはすべてのユーザーをリストしています。私は指定されたグループのメンバーであるユーザーだけを出したい。だから私は、フィルタを設定している:RXJSフィルターが別の観測にあります

private loadUsers() { 
    console.log(`Loading users...`); 
    this.graph.get$(`users`) 
     .map(resp => resp.json().value) 
     .flatMap(user => user) 
     .do(user => { 
      console.log(`Got user: ${user['displayName']}`); 
     }) 
     .filter(user => { 
      // we only want users who are members of the TrackerContact group 
      const userId: string = user['id']; 
      console.log(`Checking user ${userId}`); 
      return this.userIsTrackerContact(user); // <<= PROBLEM HERE! 
     }) 
     .subscribe(_ => { 
      console.log(`Completed user fetch!`); 
     }); 
} 

問題は、ユーザーがメンバーである、私は戻ってMS Graphに別のREST呼び出しを行う必要がありますどのようなグループを見つけるためにある:

private userIsTrackerContact(user): Observable<boolean> { 
    // get the groups this user is a member of 
    return this.graph.get$(`users/${user['id']}/memberOf`) 
     .map(resp => resp.json().value) 
     .do(groups => { 
      console.log(`${user['displayName']} is a member of ${groups.length} groups:`); 
      groups.forEach((group, idx) => { 
       console.log(` [${idx+1}]: ${group['displayName']}`); 
      }) 
     }) 
     .map(groups => { 
      const found = groups.find((group) => group['id'] === this.authConfig.azureGroups.trackerContact) 
      return !isUndefined(found); 
     }) 
} 

それは、 filterに別の観測に基づいて観測可能であると私には思われません。述語テストは単純な真偽テストでなければなりません。

Observableを別のObservableの結果に基づいてフィルタリングするにはどうすればよいですか?

+0

軽量データを得るには、サービス側でこれをフィルタリングする必要があります。両方とも同時に実行されるか? – Aravind

+0

@Aravindに同意する必要があります。すでにフィルタリングされたユーザーのコレクションをサーバーに問い合わせて、より大きなユーザーのコレクションを取得し、各ユーザーにフィルタリングするためのHTTPリクエストを作成する方が効率的です。 –

+0

@ stely000:私は原則として同意していますが、実際には全く別の手法を使ってこの問題を解決しましたが、問題は残っていると思います。それ以外の方法がない場合はどうすればよいですか? –

答えて

1

.concatAll()が良いかもしれない:

this.graph.get$(`users`) 
    .map(resp => resp.json().value) 
    .flatMap(user => user) 
    .do(user => { 
     console.log(`Got user: ${user['displayName']}`); 
    }) 
    .filter(user => { 
     // we only want users who are members of the TrackerContact group 
     const userId: string = user['id']; 
     console.log(`Checking user ${userId}`); 
     return this.userIsTrackerContact(user); // <<= PROBLEM HERE! 
    }) 
    .concatAll() 
    .subscribe(...) 

私はあなたが非同期観測はその後、フィルタmergeすることができるはずと信じています。

Rx.Observable.merge(this.graph.get$(`users`) 
    .map(resp => resp.json().value) 
    .flatMap(user => user) 
    .do(user => { 
     console.log(`Got user: ${user['displayName']}`); 
    }) 
    .map(user => { 
     // we only want users who are members of the TrackerContact group 
     const userId: string = user['id']; 
     console.log(`Checking user ${userId}`); 
     return this.userIsTrackerContact(user); // <<= PROBLEM HERE! 
    })) 
    .filter(x => x) 
    .subscribe(_ => console.info('success')); 

述語を変更するには、ユーザーisGroupMemberのプロパティを設定します。その後、filter(x => x.isGroupMember)。次に、subscribeメソッドにユーザーオブジェクトがあります。

+0

私はこれと全く違った方向に進み、私がもっと幸せな解決策を実装しました。私がやったことは、3 Observablesを発射して、すべてをPromisesに変換し、その後3つすべてで.all([...])を実行することでした。これらの3つの約束は私が必要とするすべてのデータを返しました。しかし、私はまだこの答えを受け入れるつもりです、なぜなら、実際には何の代替案もない場合にはそうだと思われるからです。 –

関連する問題