如何订阅Observable并在Javascript对象中使用该值?

时间:2019-07-05 15:02:11

标签: angular ionic-framework rxjs observable ionic4

总体而言,我对Observables,RxJS和Angular还是陌生的。我正在使用Angular 7(Ionic 4),但很难解决下面的问题。

在我的应用程序中,我发出一个HTTP GET请求,如下所示:

myData = this.http.get("https://example.com/api").pipe(
  map(results => {
    return results["payload"]
  })
)

此HTTP GET请求返回具有以下数据的Observable myData

const data = [
  {
    "id": 1,
    "name": "abc",
    "description": "test1" 
  },
  {
    "id": 2,
    "name": "def",
    "description": "test2" 
  },

  ...

  ...

]

我想向此数组中的每个对象添加另一个键color,如下所示:

const data = [
  {
    "id": 1,
    "name": "abc",
    "description": "test1",
    "color": "green"
  },
  {
    "id": 2,
    "name": "def",
    "description": "test2",
    "color": "red"
  },

  ...

  ...

]

我不是要对每个对象的color值进行硬编码,而是要从一个名为getColor(id)的服务中的函数colorService检索此键值。

问题在于colorService.getColor(id)返回一个Observable。

问题:我如何为数组中的每个对象订阅colorService.getColor(id)

我想做这样的事情:

const data = [
  {
    "id": 1,
    "name": "abc",
    "description": "test1",
    "color": <subscribe to colorService.getColor(1)>
  },
  {
    "id": 2,
    "name": "def",
    "description": "test2",
    "color": <subscribe to colorService.getColor(2)>
  },

  ...

  ...

}

我希望我明白。我的概念目前还很薄弱,因此如果其中有些听起来令人困惑,我们深表歉意。

1 个答案:

答案 0 :(得分:2)

这是您可以做的[请参见代码注释中的说明]-

myData = this.http.get("https://example.com/api")
                      .pipe(
                              mergeMap(results => {
                                const data = results["payload"];
                                //I am assuming that `data` is the array that you mentioned in your question
                                //Iterate through each of the object in the array and map it to an observable which
                                //will fetch the color and then return the data with color

                                //obs will be an array of observables for each data
                                const obs = data.map(d => {                                  
                                  return this.colorService.getColor(d.id)
                                             .pipe(
                                               map(color => {
                                                 return {...d, color};
                                               })
                                             );
                                });

                                //wait for all the obs to be returned;
                                return forkJoin(obs);
                              }),
                              tap(dataArrayWithColor => {
                                //dataArrayWithColor will have an array of object which will have data with color
                                console.log(dataArrayWithColor);
                              })
                          );

希望有帮助。