循环数组并返回Observable中每个ID的数据 [英] Loop array and return data for each id in Observable

查看:84
本文介绍了循环数组并返回Observable中每个ID的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用RxJS v6很难从子集合中检索循环中每个项目的数据.无法迭代从HTTP调用检索的throw数组.合并映射仅对需要在所有数组项目上执行的单个项目执行此操作.

Using RxJS v6 is challenging to retrieve data from sub collection for every item in the loop. There is no way to iterate throw array that is retrieved from HTTP call. Merge map does it only for single item where there is a requirement to do it on all array items.

我已经坚持了3天.我已经尝试了一切.问题在于,新的管道语法在为您提供组织代码的巧妙方法的同时,没有简单的方法来循环引发数据收集.无法使用地图javascript函数,因为它在可观察范围之外并且返回的项目不确定.在互联网上,我只能找到一个很好的单个mergeMap的基本示例.但是我需要使用 带有http调用的数组中的每个项目,并将响应附加到同一对象.

I've been stuck on this for 3 days. I've tried everything. Problem is that new pipe syntax while provides you with neat way to organise code there is no easy way to loop throw collection of data. It is impossible to use map javascript function as it is outside observable and items returned are undefined. On internet I could only find basic examples for a single mergeMap which works great. However I need to use every item in array with http call and append response to same object.

我从第三方无法控制的两个端点开始.我嘲笑了一些示例API来说明.

I start with two endpoints from 3rd party which I have no control off. I have mocked some example API to illustrate.

端点1-返回所有项目ID: http://localhost:3000/contact

Endpoint 1 - Returns all items ID's: http://localhost:3000/contact

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

端点2-返回单个项目信息: http://localhost:3000/contact/5c9dda9aca9c171d6ba4b87e

Endpoint 2 - Returns single item information: 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 +返回可观察到的嵌套数据:

DESIRED RESULT - By using RxJs v6+ return Observable with nested data:

{
  "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循环时,我只是出错,而使用不同的运算符也不能给我太多,因为RxJ中的循环存在问题.这是我产生的代码.请提供任何有用的建议或文档.

I just get errors when trying to use Javascript loop and using different operators doesn't give me much either as problem is with looping in RxJs. This is code I have produced. Please provide any useful suggestions or documentation.

testService.service.ts

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');
  }

}

我当前的最终数据看起来只是一个项目.如果我只想打一个电话,那就太好了...但是,它与上述所需的输出相差甚远.

My current end data looks like just a single item. Its great if I wanted to make just a single call... However its far from desired output described above.

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

推荐答案

使用嵌套的mergeMapmap很有可能.坚持使用Observable的一种关键方法是使用from函数将通讯录数组扩展为一个Observable.然后,您可以使用toArray运算符收集数据.提供记录的示例:

This is quite possible using nested mergeMap and map. A key approach to stick with Observable is expanding the contacts array into an observable using from function. Then you collect the data using toArray operator. Providing documented example:

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 
              (original, detail) => ({...original, relationship: detail})
            ),
            // collect all contacts into an array
            toArray(),
            // add the newly fetched data to original result
            map(contact => ({ ...result, contact})),
          )
        ),
    );
}


不建议使用结果选择器

在内部的mergeMap中,之后可以使用map.


result selector is deprecated

In the inner mergeMap, you can use a map afterwards.

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).pipe(
              map(detail => ({ ...contact, relationship: detail })),
            ),
          // collect all contacts into an array
          toArray(),
          // add the newly fetched data to original result
          map(contact => ({ ...result, contact })),
        ),
      ),
    ),
  );
}

这篇关于循环数组并返回Observable中每个ID的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆