首页 > 解决方案 > 使用firebase将promise值分配给角度全局值时的时间失败

问题描述

当我调用 getProyectos () 时出现问题,因为它在变量 this.students 还没有值时拉取变量并且我收到此错误:


ERROR Error: Uncaught (in promise): TypeError: alumnos is not iterable
TypeError: alumnos is not iterable
    at AdminpanelComponent.getProyectos (adminpanel.component.ts:300)
    at AdminpanelComponent.<anonymous> (adminpanel.component.ts:244)
    at Generator.next (<anonymous>)
    at tslib.es6.js:73
    at new ZoneAwarePromise (zone-evergreen.js:876)
    at Module.__awaiter (tslib.es6.js:69)
    at AdminpanelComponent.ngOnInit (adminpanel.component.ts:220)
    at checkAndUpdateDirectiveInline (core.js:31910)
    at checkAndUpdateNodeInline (core.js:44367)
    at checkAndUpdateNode (core.js:44306)
    at resolvePromise (zone-evergreen.js:797)
    at new ZoneAwarePromise (zone-evergreen.js:879)
    at Module.__awaiter (tslib.es6.js:69)
    at AdminpanelComponent.ngOnInit (adminpanel.component.ts:220)
    at checkAndUpdateDirectiveInline (core.js:31910)
    at checkAndUpdateNodeInline (core.js:44367)
    at checkAndUpdateNode (core.js:44306)
    at debugCheckAndUpdateNode (core.js:45328)
    at debugCheckDirectivesFn (core.js:45271)
    at Object.eval [as updateDirectives] (AdminpanelComponent_Host.ngfactory.js? [sm]:1)

这是ngOninit()的代码

ngOnInit () {
     this.getAlumnos ();
    
     this.alumnosProyectos = this.getProyectos ();} 

这是 getAlumnos() 和 getProyectos() 的代码

async getAlumnos() {
    await this.firestoreService.getUsuarios().subscribe((UsuariosSnapshot) => {
      this.alumnos = [];
      UsuariosSnapshot.forEach((alumnoData: any) => {
        if (alumnoData.payload.doc.data().rol == "Alumno") {
          this.alumno = {
            usuario: {
              id: null,
              data: null
            }
          };
          this.alumno.usuario.id = alumnoData.payload.doc.id;
          this.alumno.usuario.data = alumnoData.payload.doc.data();
          this.alumnos.push(this.alumno);
        }

      })


    });

  }

getProyectos() {
    let proyectos = []

    for (let alumno of this.alumnos) {
      let query2 =this.firestoreService.getProyectosUsuario(alumno.usuario.id).subscribe((usuario) => {
        if (usuario.length > 0) {
          proyectos.push({
            id: alumno.usuario.id,
            data: usuario[0].payload.doc.data()
          });
        }

      });

    }
    console.log("aqui", proyectos);
    return proyectos;

  }

还附上了firebase服务代码

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class FirestoreService {

  constructor(private firestore: AngularFirestore) { }
public getUsuarios() {
    return this.firestore.collection('alumnos').snapshotChanges();

  }

public getProyectosUsuario(documentId: string){
    return this.firestore.collection('alumnos').doc(documentId).collection('proyectos').snapshotChanges();
  }

非常感谢您的回复,在此先感谢。

标签: angularfirebase

解决方案


您可以在另一个函数中扭曲您的两个函数并使用 await 关键字,以等待您的 getAlumnos() 函数完成,然后再继续。嗨已经重写了你的代码,所以我应该工作。

        ngOnInit () {
         this.SomeFunctionName()
    }
    async getAlumnos() {
 this.alumnos = [];
    await this.firestoreService.getUsuarios().subscribe((UsuariosSnapshot) => {
      UsuariosSnapshot.forEach((alumnoData: any) => {
      console.log('alumno',alumnoData.payload.doc.data())
        if (alumnoData.payload.doc.data().rol == "Alumno") {
          const alumno = {
            usuario: {
              id: null,
              data: null
            }
          };
          alumno.usuario.id = alumnoData.payload.doc.id;
          alumno.usuario.data = alumnoData.payload.doc.data();
          this.alumnos.push(this.alumno);
        }
      })
      return this.alumnos;
    });
  }

    getProyectos() {
        let proyectos = []

        for (let alumno of this.alumnos) {
          let query2 =this.firestoreService.getProyectosUsuario(alumno.usuario.id).subscribe((usuario) => {
            if (usuario.length > 0) {
              proyectos.push({
                id: alumno.usuario.id,
                data: usuario[0].payload.doc.data()
              });
            }

          });

        }
        console.log("aqui", proyectos);
        this.alumnosProyecto = proyectos;

      }

      async SomeFunctionName(){

      await getAlumnos();
      getProyectos();

      }

解决此问题的另一种方法是将所有内容包装在管道中,因此函数按顺序执行,但是由于您使用异步等待,因此正如我刚刚演示的那样更容易做到。

更新的解决方案

这是有关如何使用 SwitchMap 解决它的示例

SomeFunctionName() {
    this.alumnos = [];
    this.firestoreService.getUsuarios().pipe(switchMap((UsuariosSnapshot: any) => {
        UsuariosSnapshot.forEach((alumnoData: any) => {
            //console.log('alumno', alumnoData.payload.doc.data())
            //if (alumnoData.payload.doc.data().rol == "Alumno") {
            const alumno = {
                usuario: {
                    id: null,
                    data: null
                }
            };
            alumno.usuario.id = alumnoData.payload.doc.id;
            alumno.usuario.data = alumnoData.payload.doc.data();
            this.alumnos.push(alumno);
            //}
        })
        return of(this.alumnos);
    })).subscribe(alumnos => {
        let proyectos = []

        this.alumnos.forEach(alumno => {
            let query2 = this.firestoreService.getProyectosUsuario(alumno.usuario.id).subscribe((usuario) => {
                if (usuario.length > 0) {
                    proyectos.push({
                        id: alumno.usuario.id,
                        data: usuario[0].payload.doc.data()
                    });
                }

            });

        })
        console.log("aqui", proyectos);
        this.alumnosProyectos = proyectos;
    })

}

请记住将这两行添加到您的导入中

import { switchMap } from 'rxjs/operators/';
import { of } from 'rxjs';

希望有帮助。


推荐阅读