Временной сбой при присвоении значения обещания глобальному значению в angular с помощью firebase - PullRequest
0 голосов
/ 06 мая 2020

У меня проблема, когда я вызываю 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();
  }

I буду очень признателен за ваш ответ, заранее спасибо.

1 Ответ

0 голосов
/ 06 мая 2020

Вы можете деформировать обе свои функции внутри другой функции и использовать ключевое слово await, чтобы дождаться, пока ваша функция getAlumnos () завершит sh, прежде чем продолжить. Привет, я переписал ваш код, поэтому я должен работать.

        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();

      }

Другой способ решить эту проблему - обернуть все внутри канала, поэтому функции выполняются последовательно, но поскольку вы используете asyn c await, проще сделать так, как я только что продемонстрировал. строку в ваш импорт

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

Надеюсь, что это помогло.

...