【问题标题】:Angular Firestore with Await带有等待的 Angular Firestore
【发布时间】:2019-07-08 01:47:47
【问题描述】:

查看this 答案后,我尝试将 async/await 与 firestore 调用一起使用,但我认为我遗漏了一些东西。

我正在尝试使用快照来获取十六进制网格的“十六进制”文档集合。 (我有 valueChanges 工作,但后来意识到我将需要元数据)我想获取十六进制,然后将它们排序成行,最后将它们返回给组件。我可以看到它在快照和管道操作完成之前返回,因为它是空的“hexRows ['test']”被控制台注销为“true”。

TS:

服务:

async getHexesInRows(){
    let hexRows = {test: true}
    this.hexCollection = this.db.collection('hexes', ref=> ref.orderBy('id').limit(5))

this.hexes = await this.hexCollection
  .snapshotChanges()
  .pipe(
    map(actions => actions.map( hex => {
      const data = hex.payload.doc.data()
      const uid = hex.payload.doc.id
      return {uid, ...data}
    })),
    map(data => {
      data.forEach((hex, index) => {
        let rowNum = Math.floor(index / 10)
        hexRows = {test: false}

        if(hexRows[`row${rowNum}`] == undefined){
          hexRows[`row${rowNum}`] = []
        }
        hexRows[`row${rowNum}`].push(hex)
      })
      return data
    })
  )
console.log('Rows', hexRows);
console.log('Hexes', this.hexes);

return hexRows
  }

组件

hexRows: any

  constructor(public dialog: MatDialog, public afs: FirestoreService) { }
  ngOnInit() {
    this.hexRows = this.afs.getHexesInRows()
  }

【问题讨论】:

    标签: angular firebase async-await rxjs google-cloud-firestore


    【解决方案1】:

    您不能像 Promise 那样等待 Observable,而是订阅 Observable,您需要来自 Observable 的数据。你通常从你的服务中返回 Observables 并在你的组件中订阅它们。

    从你的服务中返回一个 Observable

    getHexesInRows(){
      this.hexCollection = this.db.collection('hexes', ref => ref.orderBy('id').limit(5))
    
      return this.hexCollection
        .snapshotChanges()
        .pipe(
          map(actions => actions.map( hex => {
            const data = hex.payload.doc.data()
            const uid = hex.payload.doc.id
            return {uid, ...data}
          })),
          map(data => {
            let hexRows = {test: true}
            data.forEach((hex, index) => {
              let rowNum = Math.floor(index / 10)
              hexRows = {test: false}
    
              if(hexRows[`row${rowNum}`] == undefined){
                hexRows[`row${rowNum}`] = []
              }
              hexRows[`row${rowNum}`].push(hex)
            })
            return hexRows
          }),
          // tap(hexRows => this.hexRows = hexRows), // if you need the hexes in your Service but you usually shouldn't
          tap(hexRows => console.log('Rows', hexRows)) // if you want to log something in your Service
        );
    }
    

    订阅组件中的 Observable

    hexRows: any
    
    constructor(public dialog: MatDialog, public afs: FirestoreService) { }
    
    ngOnInit() {
      this.afs.getHexesInRows().subscribe(hexes => this.hexRows = hexes);
    }
    

    【讨论】:

    • 我最终只是在我的组件上订阅了十六进制并在该订阅中进行了排序,所以这与您所描述的不完全一样,但您肯定让我获得了 95% 的成功,哈哈。只是为了澄清以防有人试图做类似的事情。
    • @gv0000 我刚刚注意到我在最后一个map 中返回了data 而不是hexRows 并修复了它。当您订阅时,您现在应该在您的组件中获得hexRows,并且不必在您的组件中进行排序。如果可以的话,将数据处理逻辑移至服务并为您的组件提供干净的数据通常是一种很好的做法。
    【解决方案2】:

    您不能等待 Observable,尝试通过添加 toPromise 将其更改为 Promise

    this.hexCollection
      .snapshotChanges()
      .pipe(
        map(actions => actions.map( hex => {
          const data = hex.payload.doc.data()
          const uid = hex.payload.doc.id
          return {uid, ...data}
        })),
        map(data => {
          data.forEach((hex, index) => {
            let rowNum = Math.floor(index / 10)
            hexRows = {test: false}
    
            if(hexRows[`row${rowNum}`] == undefined){
              hexRows[`row${rowNum}`] = []
            }
            hexRows[`row${rowNum}`].push(hex)
          })
          return data
        }),
        toPromise()
      )
    

    【讨论】:

      猜你喜欢
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2019-01-22
      • 2014-03-30
      • 2022-01-07
      • 2020-07-02
      • 1970-01-01
      相关资源
      最近更新 更多