Estoy tratando de determinar cómo / si puedo convertir un rechazo de Promesa en un Observable escrito.

Tengo un componente de inicio de sesión con una función como esta ...

login() {
  const login$ = this.authenticationService.login(this.loginForm.value)
  login$
  .pipe(
    finalize(() => {
      this.loginForm.markAsPristine();
      this.isLoading = false;
    }),
    untilDestroyed(this)
  )
  .subscribe(
    (credentials) => {
      log.debug(`${credentials.username} successfully logged in`);
      this.router.navigate([this.route.snapshot.queryParams.redirect || '/'], { replaceUrl: true });
    },
    (error) => {
      log.debug(`Login error: ${error}`);
      this.error = error;
    }
  )
}

Y un servicio de autenticación con un método como este ...

login(context: LoginContext): Observable<Credentials> {

  var data = {} as Credentials
  
  // Call a method that returns a Promise
  this.server.authenticate(LoginContext)
  .then((result) -> {
      data.username = result.user.username
      data.token = result.accessToken
      this.credentialsService.setCredentials(data, context.remember)
      // Not sure what to do here...need to return data somehow as an Observable
      // return data
    })
  .catch((err) => {
      // Not sure what to do here either...need to bubble the err up so that it's caught in subscribe
      // return throwError(err)
    })
}

¿Cómo puedo devolver un Observable<Credentials> si la Promesa se resuelve y mostrar el error si se rechaza?

Sé que puedo hacer que todo funcione si cambio la función del servicio de autenticación para que devuelva Promise<Observable<Credentials>>, lo cual está bien, pero para aprender cosas nuevas, estoy tratando de averiguar si esto es posible.

0
forgot 21 oct. 2020 a las 23:01

1 respuesta

La mejor respuesta

Puede utilizar la from función para convertir cualquier { {X1}} a Observable:

import { from } from 'rxjs';

// ...

class YourClass {
  login(context: LoginContext): Observable<Credentials> {
    return from(this.server.authenticate(LoginContext).then(result => {
      const credentials: Credentials = {
        username: result.user.username,
        token: result.accessToken
      }; 
      this.credentialsService.setCredentials(credentials, context.remember);
      return credentials;
    }));
  }
}
2
Jacob 21 oct. 2020 a las 20:22