Search code examples
javascriptangularionic-frameworkrxjses6-promise

Why the 'toPromise()' doesn't work for me when


I explain my problem with the code example

I have the following service:

@Injectable()
export class PartidoProvider extends MyFirestoreProvider<Partido> {

 constructor(  public http: HttpClient,
               public firestore: AngularFirestore) {      
    super('partidos', http, firestore);        
  }

 buscarPartido ( jugador1: Jugador, jugador2: Jugador ) : Observable<Partido[]> {
    let partidoGanaJugador1: Partido = new Partido();
    let partidoPierdeJugador1: Partido = new Partido();

    partidoGanaJugador1.jugadorGanador = jugador1.idDoc;
    partidoGanaJugador1.jugadorPerdedor = jugador2.idDoc;

    partidoPierdeJugador1.jugadorGanador = jugador2.idDoc;
    partidoPierdeJugador1.jugadorPerdedor = jugador1.idDoc;

    return Observable.zip(  this.get(partidoGanaJugador1), 
                        this.get(partidoPierdeJugador1), 
                        (listaGanados, listaPerdidos) => {                                  
                              return listaGanados.concat(listaPerdidos);
    });    
}

From a component I need to invoke the service converted to a promise to later use await to wait for the data to return in order to manage the registration in another entity.

Next I show the code of tests of the calls to the service:

  async enviarResultado(){
    let rival: Jugador;
    let jugador: Jugador = this.authProvider.jugador;
    let nombreRival: string;
    let partido: Partido;
   // Obtener partido del calendario para añadirle el resultado    
    nombreRival = this.myForm.controls['rival'].value;        
    rival = this.rivales.find( rival => rival.nombre == nombreRival);    

    // THIS WORKS
    const sample = val => Observable.of(val).delay(5000);
    const example = sample('First Example').toPromise().then(result => {
     console.log('From Promise:', result);
          });

    // THIS WORKS
    this.partidoProvider.buscarPartido(jugador, rival).subscribe(
      resultado => {
        console.log("El subscribe ha devuelto datos");
        console.log(resultado);          
      },
      error => {
        console.error("Se ha producido un error al intentar buscar el partido para modificar el resultado")
      }
  );

   // THIS DOESN'T WORK only 1 appears in the debug console (console.log ("1"))
   console.log("1"); 
   this.partidoProvider.buscarPartido(jugador, rival).toPromise()
   .then( lista => {
     console.log("2");
     console.log("Promesa entra");
     console.log("data:" + lista);                      
     if ( lista && lista.length > 0){
       partido = lista[0]
     }
   })
   .catch( error => {
     console.log("2");
     console.error("Se ha producido un error al intentar buscar el partido para modificar el resultado")
    });    

Does anyone have any idea what is wrong?

Thank you very much in advance


Solution

  • When using toPromise() you need to be sure that the source Observables completes.

    Observables can emit multiple values so toPromise() can't know what is the last value and when it should resolve the Promise it returns.

    So my guess is that one of the source Observables created with this.get(...) never completes. Maybe you want to use something like this Observable.zip(...).take(1).