Angular HttpClient Observable从带有管道()和map()的嵌套哈希中获取数组

时间:2019-05-13 16:56:21

标签: angular ionic-framework rxjs ionic4

我对不了解的RXJS Observables和管道有一些问题。

我的API返回这样的响应

    {
      "_embedded": {
        "users": [
          {
             "id": 1,
             "username": "steve"
          }
        ]
      }
    }

我有以下功能(此问题非常简化):

  listUsers() {
    return this.http.get<Users>(API_BASE_URL + '/v1/users').pipe(map(u => u._embedded.users))
  }

  getFirstUser() {
    return this.listUsers().pipe(first())
  }

  listUsersById() {
    return this.listUsers().pipe(reduce((acc, user) => { 
      acc[user.id] = user
      return acc
    }, {}))
  }

这是我的测试方式:

this.listUsers().subscribe(data => {
  console.log("FUNC: listUsers()")
  console.log(data)
  console.log(data[0])
})

this.listUsersById().subscribe(data => {
  console.log("FUNC: listUsersById()")
  console.log(data)
  console.log(data[0])
})

this.getFirstUser().subscribe(data => {
  console.log("FUNC: getFirstUser()")
  console.log(data)
})   

listUsers()达到了我的期望,注销了11个用户对象的数组,然后注销了该数组中的第一个用户对象。

listUsersById()注销{undefined:[由11个用户对象组成的数组]},应该是一个哈希,其中键是id,值是用户对象。

getFirstUser()注销11个用户对象的数组(应该是一个)

问题似乎是rxjs并未将listUsers()的返回值视为“内部”数组,这使我的管道功能无法使用。

我想要的是创建“数据管道”,而无需解决功能,直到需要为止。使用返回承诺的Angular HTTPClient时,我应该如何正确执行此操作?

如果我解决了http请求,并且将数据放在一个数组中,则它可以正常工作。

from([
      {
        id: 1,
        username: "steve"
      },
      {
        id: 2,
        username: "jane"
      }
    ]).pipe(reduce((acc, user) => {
      acc[user.id] = user
      return acc
    }, {}))

1 个答案:

答案 0 :(得分:1)

正如@ jb-nizet在他的评论中解释的那样,该事件仅发出一次。

基于此,一种解决listUsersById()的简单实现方法是:

  listUsersById() {
    return this.listUsers().pipe(map(u => u.reduce((acc, user) => { 
      acc[user.id] = user
      return acc
    }, {})))
  }

另一种选择是使用flatMap()为数组中的每个项目发出一个事件,如下所示:

  listUsers() {
    return this.http.get<Users>(API_BASE_URL + '/v1/users').pipe(map(u => u._embedded.users), flatMap(x => x))
  }

通过这种方式,getUsersById()的原始实现可以按需工作,但就我而言,以这种方式进行操作毫无意义。