Как сделать вызов, используя данные предыдущего и объединить данные результата вместе? - PullRequest
0 голосов
/ 18 мая 2019

У меня есть API, который я не могу изменить.Я должен использовать данные как есть.

Я хочу объединить данные из двух отдельных запросов, где второй запрос основан на данных из первого.

У меня уже есть работающее решение, но качество кода, на мой взгляд, низкое, поэтому я хочу узнать ваше мнение (и если вы можете предоставить: лучшее, более реактивное решение).

Итак, у меня есть API order , который получает данные:

/orders ответ:

[
  {
    id: 1,
    clientId: 201,
    // other data
  },
  {
    id: 2,
    clientId: 201,
  },
  {
    id: 3,
    clientId: 11,
  }
]

В этом ответе у меня нет данных о клиентеимя, поэтому у меня есть второй API, где я могу передать идентификаторы клиентов, а затем я вернулся:

/clientsData?ids=201,11 ответ:

[
  {
    id:201,
    name: "Jon Doe"
  },
  {
    id: 11,
    name: "Jack Sparrow"
  }
]

Итак, теперь у меня есть рабочий код, нокак уже упоминалось, в начале я чувствую, что это можно сделать лучше.Обратите внимание, что запрос должен быть выполнен в правильном порядке, потому что мне нужны идентификаторы клиентов, прежде чем я сделаю второй вызов API.

Кроме того, нужно избегать множественных (более двух [заказов + клиентов]) запросов напроверьте данные клиента.

Рабочий код:


// API Call to get orders:
const result$ = this.http.get('/orders').pipe(
  mergeMap(
    orders => {
      const ids = orders
        .map(item => item.clientId)
        .filter((v, i, a) => a.indexOf(v) === i) // remove duplicates
        .join(','); // get client ids into one string

      // Client IDs: 1,2,99,201
      // API call to check IDs:
      return this.http.get(`/clientsData?ids=${ids}`).pipe(
        mergeMap(clientsData => {
          // map over each client
          clientsData.forEach(client => {
            // then map over each order
            orders.forEach(order => {
              // and assign client name to order
              if (order.clientId === client.id) {
                order.clientName = client.name;
              }
            });
          });

          return of(orders); // observable
        })
      );
    }
  )
);

result$.subscribe(console.log);

Я ожидаю получить обратно Наблюдаемый с объединенными данными:

[
  {
    id: 1,
    clientId: 201,
    name: "Jon Doe"
    // other data
  },
  {
    id: 2,
    clientId: 201,
    name: "Jon Doe"
  },
  {
    id: 3,
    clientId: 11,
    name: "Jack Sparrow"
  }
]

Я хочу избежать вложенных подписок и достичьрезультат в реактивном ключе.

...