web-dev-qa-db-ja.com

Angular 6パイプRxJsオペレーターが3つの依存オブザーバブルをチェーンする

次のような3つの依存するRest APIリソース(オブザーバブルと言います)があります。

最初のオブザーバブルは、次のようにユーザーの配列として1つのアイテムを生成します。

getUsers(): Observable<User[]>
    [
      {
        "id": 1,
        "name": "Peter",
        "surname": "Smith"
      },
      {
        "id": 2,
        "name": "John",
        "surname": "Wayne"
      },
      ...
    ]

2番目のobservableはユーザーに割り当てられたアドレスを取得するために使用できるため、入力パラメーターはユーザーIDであり、1つのアイテムをアドレスの配列として返します。

getUserAddresses(user_id: string): Observable<Address[]>
    [
      {
        "id": 1,
        "city": "London",
        "street": "Wicombe 34"
      },
      {
        "id": 2,
        "city": "Paris",
        "street": "La fever 20"
      },
      ...
    ]

3番目のobservableは、ユーザーに割り当てられた企業を取得するために使用できるため、入力パラメーターはUser IDであり、企業の配列として1つのアイテムを返します。

getUserCompanies(user_id: string): Observable<Company[]>
    [
      {
        "id": 1,
        "name": "Fintch CO",
        "state": "France"
      },
      {
        "id": 2,
        "name": "C&C inc.",
        "state": "USA"
      },
      ...
    ]

これらの3つのオブザーバブルを1つのアイテムとして再び生成し、次のように追加のアドレス配列と企業配列を持つユーザーの配列を含む1つのオブザーバブルを連鎖させたいと思います:

    [
      {
        "id": 1,
        "name": "Peter",
        "surname": "Smith",
        "addreesses": 
               [
                 {
                   "id": "1",
                   "city": "London",
                   "street": "Wicombe 34"
                 },
                 {
                   "id": "2",
                   "city": "",
                   "street": "La fever 20"
                 }
               ],
        "companies": 
               [
                 {
                   "id": "1",
                   "name": "Fintch CO",
                   "state": "France"
                 },
                 {
                   "id": "2",
                   "name": "C&C inc.",
                   "state": "USA"
                 }
               ]
        }
      },
      {
        "id": 2,
        "name": "John",
        "surname": "Wayne",
        "addresses": [...],
        "companies": [...],
      },
      ...
    ]

RxJs 6を使用してAngular 6でそれを実現するために、演算子の複合はどのように見える必要がありますか?アドバイスをありがとう。

11
Peter

このような何かが動作する可能性があります

getUsers()
.pipe(
  switchMap(users => from(users)),
  mergeMap(user => forkJoin(getAddresses(user.id), getCompanies(user.id))
                   .pipe(map(data => ({user, addresses: data[0], companies: data[1] })))
  tap(data => data.user.addresses = data.addresses),
  tap(data => data.user.addresses = data.companies),
  map(data => data.user),
  toArray()
  )
)

別のユースケースに適用すると、同様のチェーンが詳細に説明されます ここ

11
Picci

オブザーバブルをチェーンするには、flatMap関数を使用できます。この関数は、promiseのようなものです。つまり、Observableが値に解決された後にのみ関数が実行されます。

forkJoinと呼ばれる監視可能な関数もあります。これにより、複数の非同期要求がすべて値に解決されるのを待つことができます。

例:

getUsers().flatMap((users) => {
    // the users variable is the list of users
    var multipleObservables = [];
    users.forEach((u) => {
      multipleObservables.Push(
         getUserAddresses(u.id).map((usersAddresses) => {
            u.addresses = usersAddresses;
            return u;
         });
      );
    });
    return forkJoin(multipleObservables);
}).flatMap((usersWithAddresses) => {
    // the usersWithAddresses variable is an array of users which also have their addresses
    var multipleObservables = [];
    usersWithAddresses.forEach((u) => {
       multipleObservables.Push(
          getUserCompanies(u.id).map((usersCompanies) => {
             u.companies = usersCompanies;
             return u;
          });
       );
    });
    return forkJoin(multipleObservables);
});

このようなものを記述して、リクエストをチェーン化し、ユーザーオブジェクトを成長させることができます。

3
brad mcallister

以下に組み合わせの演算子を示します。これらは配列で結果を出力します( reference ):

あなたが好むものを見つけ出し、あなたのシナリオに最適なものを見つけるために、それらすべてを読むことをお勧めします。

お役に立てれば!

0
Jmsdb