【问题标题】:Angular Firestore combineLatest with multiple queriesAngular Firestore combineLatest 与多个查询
【发布时间】:2020-04-17 17:01:22
【问题描述】:

我在使用 Angular9、Firestore6 和 combineLatest rxjs 运算符时遇到了一些问题。

我有一个 users 集合和另一个 items 集合。一个用户可以有多个项目,但采用老式的多对多关系方式,其中项目是主数据(不可修改),桥接表将两个集合与附加数据连接起来:

  • 项目

    • 苹果
      • 名称:“苹果”
      • 颜色:“绿色”
  • 用户

    • 项目
      • uid
        • uid:“苹果”
        • 数量:23

所以我需要获取登录user的项目列表,加入两个集合:

  • 用户
    • 项目
      • 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&lt;any&gt;],它没有编译,因为Property 'find' does not exist on type 'Observable&lt;any&gt;'

我想这是因为第二个.valueChanges() 没有得到解决,但我不知道我做错了什么。谁能帮帮我?

我已经尝试过其他答案,例如this one,但到目前为止没有运气。

提前致谢。

【问题讨论】:

    标签: javascript angular google-cloud-firestore


    【解决方案1】:

    您非常接近,您只需向userItems.map 添加一个扩展运算符,并且您需要从 userItem 对象中获取itemId(只是猜测):

    return combineLatest([
      of(userItems),
      ...userItems.map(
        userItem => this.angularFirestore.doc<any(`items/${userItem.itemId}`).valueChanges()
      )
    ])
    

    combineLatest 需要 Observables 的数组。让我们忽略of(userItems) 如果你只是这样做:

    combineLatest([
      userItems.map((userItem) => this.af.valueChanges())
    ]) 
    

    你最终会在一个数组中得到一个数组,所以基本上是Observable[][]。这就是为什么您需要使用扩展运算符将项目放入周围数组中的原因。如果你没有of(userItems),你可以这样做:

    combineLatest(
      userItems.map((userItem) => this.af.valueChanges())
    ) 
    

    所以没有包装数组,但因为您还需要userItems,所以将它们添加到顶部是一个很好的解决方案。

    不过,我确实注意到了一些其他错误,这些错误可能对您不起作用。最后一张地图中的items 只是一个项目,而不是一个数组。要将其放入您期望的数组中,您再次需要在 items 参数上使用扩展运算符,在本例中是一个休息运算符,如下所示:

    map(([userItems, ...items]) => {
    

    【讨论】:

    • 就是这样,现在它按预期工作了。非常感谢你! @pierreduc 您能否详细说明 为什么 需要扩展运算符才能将 Observable 实际解析为 combineLatest() 运算符中的对象?
    猜你喜欢
    • 1970-01-01
    • 2018-05-18
    • 2023-03-09
    • 2019-04-05
    • 2020-07-14
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多