Angular Firestore将最新与多个查询结合在一起 [英] Angular Firestore combineLatest with multiple queries

查看:38
本文介绍了Angular Firestore将最新与多个查询结合在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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 because Property '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 the itemId (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 of Observables. Let's ignore the of(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 the of(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将最新与多个查询结合在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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