Angular HttpClient Observable 使用 pipes() 和 map() 从嵌套散列中获取数组
Angular HttpClient Observable get array from nested hash with pipes() and map()
我对 RXJS Observables 和管道有一些我不理解的问题。
我的APIreturn是这样的回复
{
"_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() logs out { undefined: [array of 11 user objects] }, 应该是一个散列,其中键是 id,值是用户对象。
getFirstUser() 登出一个包含 11 个用户对象的数组(应该是一个)
问题似乎是 rxjs 没有将 listUsers() 中的 return 值视为数组 "internally",这使得我的管道函数无法使用。
我想要的是创建 "data pipeline" 直到需要时才解析函数。使用 return 承诺的 Angular HTTPClient 时,我应该如何正确执行此操作?
如果我解析了 http 请求并在数组中提供了可用数据,它就可以正常工作。:
from([
{
id: 1,
username: "steve"
},
{
id: 2,
username: "jane"
}
]).pipe(reduce((acc, user) => {
acc[user.id] = user
return acc
}, {}))
正如@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() 的原始实现可以按需工作,但在我的情况下,这样做没有意义或意义不大。
我对 RXJS Observables 和管道有一些我不理解的问题。
我的APIreturn是这样的回复
{
"_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() logs out { undefined: [array of 11 user objects] }, 应该是一个散列,其中键是 id,值是用户对象。
getFirstUser() 登出一个包含 11 个用户对象的数组(应该是一个)
问题似乎是 rxjs 没有将 listUsers() 中的 return 值视为数组 "internally",这使得我的管道函数无法使用。
我想要的是创建 "data pipeline" 直到需要时才解析函数。使用 return 承诺的 Angular HTTPClient 时,我应该如何正确执行此操作?
如果我解析了 http 请求并在数组中提供了可用数据,它就可以正常工作。:
from([
{
id: 1,
username: "steve"
},
{
id: 2,
username: "jane"
}
]).pipe(reduce((acc, user) => {
acc[user.id] = user
return acc
}, {}))
正如@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() 的原始实现可以按需工作,但在我的情况下,这样做没有意义或意义不大。