问题描述
我在Angular9,Firestore6和 combineLatest
rxjs运算符上遇到了一些麻烦.
I'm having a little trouble with Angular9, Firestore6 and the combineLatest
rxjs operator.
我有一个 users
的集合,和另一个 items
的集合.一个用户可以拥有多个项目,但是采用一种老式的多对多关系方式,其中,这些项目是主数据(不可修改),而桥接表将两个集合与其他数据连接在一起:
I have one collection of users
, and another collection of items
. One user can have several items, but in an old fashioned manyToMany relationship way, in which the items are master data (non modifiable) and the bridge table joins both collections with additional data:
-
项目
- 苹果
- 名称:苹果"
- 颜色:绿色"
用户
- 项
- uid
- uid:苹果"
- 数量:23
因此,我需要获取已登录的
user
用户的项目列表,并同时加入这两个集合:So I need to get a list of the items of the logged in
user
, joining both collections:- 用户
- 项
- uid
- uid:苹果"
- 数量:23
- 加入
- 名称:苹果"
- 颜色:绿色"
这是我的代码:
import { AngularFireAuth } from '@angular/fire/auth'; import { AngularFirestore } from '@angular/fire/firestore'; import { switchMap, map } from 'rxjs/operators'; import { combineLatest, of } from 'rxjs'; getUserItems() { return this.angularFireAuth.authState.pipe( switchMap(user => { if (user) { return this.angularFirestore.collection<any>(`users/${user.uid}/items`).valueChanges() .pipe( switchMap(userItems=> { return combineLatest([ of(userItems), userItems.map(userItem=> this.angularFirestore.doc<any>(`items/${userItem}`).valueChanges()) ]) }), map(([userItems, items]) => { console.log(userItems, items); return userItems.map(userItem => { return { ...userItem, join: items.find(item => item.uid === userItem.uid) } }) }) ) } }) ) }
但是在
map(([[userItems,items])
,而不是[any [],any []]
中,我得到了[any [],Observable< any>]
,它不会编译,因为属性'find'在'Observable< any>'
类型上不存在.But in the
map(([userItems, items])
, instead of[any[], any[]]
, I get[any[], Observable<any>]
, it does not compile becauseProperty 'find' does not exist on type 'Observable<any>'
.我想这是因为第二个
.valueChanges()
尚未解决,但是我不知道自己在做什么错.有人可以帮我吗?I guess it's because the second
.valueChanges()
is not getting resolved, but I don't know what I'm doing wrong. Can anyone help me out?我已经尝试了其他答案,例如这个答案,但是到目前为止还没有运气.
I already tried other answers like this one but with no luck so far.
谢谢.
推荐答案
您非常接近,您只需要在
userItems.map
中添加一个扩展运算符,就需要获取 itemId (仅是一个猜测):You were very close, you just need to add a spread operator to the
userItems.map
and you need to get theitemId
(just a guess) from the userItem object:return combineLatest([ of(userItems), ...userItems.map( userItem => this.angularFirestore.doc<any(`items/${userItem.itemId}`).valueChanges() ) ])
combineLatest
需要一个数组Observables
.让我们忽略of(userItems)
,如果您这样做:The
combineLatest
wants an array ofObservables
. Let's ignore theof(userItems)
If you just do:combineLatest([ userItems.map((userItem) => this.af.valueChanges()) ])
您最终将在数组内部找到一个数组,因此基本上是
Observable [] []
.这就是为什么您需要使用散布运算符将项目放在周围的数组中的原因.如果您没有of(userItems)
,则可以这样做:You will end up with an array inside of an array, so basically
Observable[][]
. That's why you need to use the spread operator, to put the items in the surrounding array. If you did not have theof(userItems)
, you could have just done:combineLatest( userItems.map((userItem) => this.af.valueChanges()) )
因此没有包装数组,但是由于还需要
userItems
,因此将它们添加到顶部是一个很好的解决方案.So without the wrapping array, but because you need the
userItems
as well, it's a nice solution to add them to the top.但是,我确实注意到了其他一些错误,这些错误可能对您不起作用.最后一张地图中的
items
只是一项,而不是数组.要将其放入您期望的数组中,您再次需要在items参数上使用散布运算符,在这种情况下为rest运算符,如下所示:I do however noticed a couple of other mistakes, which will probably not make it work for you. The
items
in the last map, is just one item, and not an array. To get it into the array you expect, you again need to use the spread operator, which in this case is a rest operator, on the items parameter, like this:map(([userItems, ...items]) => {
这篇关于Angular Firestore将最新与多个查询结合在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- uid
- 项
- uid