Массив циклов и возвращаемые данные для каждого идентификатора в Observable - PullRequest
1 голос
/ 04 апреля 2019

Использование RxJS v6 является сложной задачей для извлечения данных из подколлекции для каждого элемента в цикле.Нет способа перебрать массив throw, полученный из HTTP-вызова.Карта слияния делает это только для одного элемента, где это требуется для всех элементов массива.

Я застрял на этом в течение 3 дней.Я перепробовал все.Проблема заключается в том, что новый синтаксис канала обеспечивает удобный способ организации кода, а не простой способ зацикливания сбора данных.Невозможно использовать функцию javascript карты, поскольку она находится вне наблюдаемой области, а возвращаемые элементы не определены.В интернете я мог найти только основные примеры для единой карты слияния, которая прекрасно работает.Однако мне нужно использовать каждый элемент в массиве с вызовом http и добавить ответ к тому же объекту.

Я начинаю с двух конечных точек от третьей стороны, которые я не могу контролировать.Я высмеял некоторые примеры API для иллюстрации.

Конечная точка 1 - возвращает идентификаторы всех элементов: http://localhost:3000/contact

{
  "name": "test",
  "contact": [
    {
      "_id": "5c9dda9aca9c171d6ba4b87e"
    },
    {
      "_id": "5c9ddb82ca9c171d6ba4b87f"
    },
    {
      "_id": "5c9ddb8aca9c171d6ba4b880"
    }
  ]
}

Конечная точка 2 - возвращает информацию об одном элементе: http://localhost:3000/contact/5c9dda9aca9c171d6ba4b87e

[
   {
     "_id": "5c9dda9aca9c171d6ba4b87e",
     "firstName": "Luke",
     "lastName": "Test",
     "email": "vgadgf@adsgasdg.com",
     "created_date": "2019-03-29T08:43:06.344Z"
   }
]

Желаемый результат - Поиспользование RxJs v6 + return Observable с вложенными данными:

{
  "name": "test",
  "contact": [
    {
      "_id": "5c9dda9aca9c171d6ba4b87e".
      "relationship":  {
                         "_id": "5c9dda9aca9c171d6ba4b87e",
                         "firstName": "Luke",
                         "lastName": "Test",
                         "email": "vgadgf@adsgasdg.com",
                         "created_date": "2019-03-29T08:43:06.344Z"
                       }
    },
    {
      "_id": "5c9ddb82ca9c171d6ba4b87f",
      "relationship": {
                         "_id": "5c9ddb82ca9c171d6ba4b87f",
                         "firstName": "Name2",
                         "lastName": "Test2",
                         "email": "vgadgf@adsgasdg2.com",
                         "created_date": "2019-03-29T08:43:06.344Z"
                       }
    },
    {
      "_id": "5c9ddb8aca9c171d6ba4b880",
      "relationship": {
                         "_id": "5c9ddb8aca9c171d6ba4b880",
                         "firstName": "Name3",
                         "lastName": "Test3",
                         "email": "vgadgf@adsgasdg3.com",
                         "created_date": "2019-03-29T08:43:06.344Z"
                       }
    }
  ]
}

Я просто получаю ошибки, когда пытаюсь использовать цикл Javascript, и использование разных операторов не дает мне много, так как проблема с циклом в RxJs.Это код, который я создал.Пожалуйста, предоставьте любые полезные предложения или документацию.

testService.service.ts

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {concatMap, map, mergeMap} from 'rxjs/operators';

@Injectable()
export class TestServiceService {

  constructor(
    private http: HttpClient
  ) { }

  public getCombinedData(): Observable<any> {
    return this.getMultipleRelationData()
      .pipe(
        map((result: any) => {
          result = result.contact;

          return result;
        }),
        mergeMap((fullResults: any) => {
          return fullResults[0].relationship = this.getSingleData(fullResults[0]._id);
        })
      );
  }

  public getSingleData(id): Observable<any> {
    return this.http.get('http://localhost:3000/contact/' + id);
  }

  public getMultipleRelationData(): Observable<any> {
    return this.http.get('http://localhost:3000/contact');
  }

}

Мои текущие конечные данные выглядят как один элемент.Замечательно, если бы я хотел сделать всего один вызов ... Однако это далеко от желаемого результата, описанного выше.

  [
  {
    "_id": "5c9dda9aca9c171d6ba4b87e",
    "firstName": "Luke",
    "lastName": "Test",
    "email": "vgadgf@adsgasdg.com",
    "__v": 0,
    "created_date": "2019-03-29T08:43:06.344Z"
  }
]

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Это вполне возможно при использовании вложенных mergeMap и map. Ключевой подход к использованию Observable - расширение массива контактов в observable с использованием функции from. Затем вы собираете данные, используя оператор toArray. Предоставление документированного примера:

public getCombinedData(): Observable<any> {
    return this.getMultipleRelationData()
      .pipe(
        mergeMap((result: any) => 

          // `from` emits each contact separately 
          from(result.contact).pipe(
            // load each contact
            mergeMap(
              contact => this.getSignleData(contact._id),
              // in result selector, connect fetched detail data
              (original, detail) => ({...original, relationship: detail})
            ),
            // collect all contacts into an array
            toArray(),
            // add the newly fetched data to original result
            map(contact => ({ ...result, contact})),
          )
        ),
    );
}
0 голосов
/ 04 апреля 2019

Хотя ответ Кветиса может помочь вам, вот что я реализовал, просто опубликовал его, потому что мне было интересно его решить.

  public getCombinedData(): Observable<any> {
    return this.getMultipleRelationData()
      .pipe(
        mergeMap((result: any) => {
          let allIds = result.contact.map(id => this.getSingleData(id._id));
          return forkJoin(...allIds).pipe(
            map((idDataArray) => {
              result.contact.forEach((eachContact, index) => {
                eachContact.relationship = idDataArray[index];
              })
              return result;
            })
          )
        })
      );
  }

Вот пример решения вашего вопроса, я сделал фиктивные Observables. https://stackblitz.com/edit/angular-tonn5q?file=src%2Fapp%2Fapi-calls.service.ts

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...