合并可能具有空值的可观察物

时间:2019-07-14 18:15:54

标签: typescript rxjs observable

我在使用Observables时遇到了麻烦(我没有Observables的经验)。

场景是:

  • 我有一个复杂的对象,需要使用HTTP服务填充。
  • 该对象中的每个属性都不依赖于另一个。
  • 服务可以返回空值。

几次尝试失败后,我得到以下代码:

我的组件

  startForm() {
    // En primer lugar construyo un formulario.
    this.buildForm(new Usuario());

    // Si es una recuperación, cargo sus detalles; si no los creo de nuevos.
    if (this.mailUsuario) {
      this.usuario = this.usuariosService
        .getUsuarioFromMail(this.mailUsuario)
        .pipe(switchMap(user => this.usuariosService.processUsuarioObservable(user)))
        .pipe(tap(usuario => this.userForm.patchValue(usuario)));

      this.usuario.subscribe(finalUser => {
        this.mapUser(finalUser);
      }, () => {
      }, () => this.logService.info('COMPLETE =>'));

    } else {
      this.startNewUserForm();
    }
  }

我的服务:

  processUsuarioObservable(usuario: Usuario): Observable<Usuario> {
    const curriculum: Observable<Fichero>[] = usuario.curriculum.map(fichero => this.ficheroService.processFileUrl(fichero));
    const curriculumForkJoin: Observable<Fichero[]> = forkJoin(curriculum).pipe(map(fichero => fichero));
    const fotoPerfil: Observable<Fichero> = this.ficheroService.processFileUrl(usuario.fotoPerfil);

    return zip(fotoPerfil, curriculumForkJoin)
      .pipe(tap(vb => this.log.info('forkJoin' + JSON.stringify(vb))))
      .pipe(map(result => {
        const finalUser = usuario;
        finalUser.fotoPerfil = result[0];
        finalUser.curriculum = result [1];
        // finalUser.ficheros = result[2];
        return finalUser;
      }));
  }

最后是文件的服务

  getFileSrcUrl(fileKey: String): Observable<UrlModel> {
    return fileKey ? this.api.get(`${EndPoints.FICHEROS}/${fileKey}/url`) : EMPTY;
  }

  /// ...
  
  processFileUrl(fichero: Fichero): Observable<Fichero> {
    return this.getFileSrcUrl(fichero.awsKey)
      .pipe(map(urlModel => {
        fichero.urls = urlModel;
        return fichero;
      }));
  }

问题在于,当最新呼叫返回EMPTY时,我的订阅无法使用。

我认为我的问题是我为processUsuarioObservable方法选择的运算符,但我在文档中找不到正确的方法。

有人可以帮助我吗?

(我也在学习英语)

1 个答案:

答案 0 :(得分:0)

将EMPTY替换为of(null)或任何适当的默认值

  getFileSrcUrl(fileKey: String): Observable<UrlModel> {
    return fileKey ? this.api.get(`${EndPoints.FICHEROS}/${fileKey}/url`) : of(null);
  }


  processFileUrl(fichero: Fichero): Observable<Fichero> {
    return this.getFileSrcUrl(fichero.awsKey)
      .pipe(map(urlModel => {
        if (urlModel) // depends on what you think urls should be in the empty case? maybe an empty array?
          fichero.urls = urlModel;
        return fichero;
      }));
  }

或者,如果您实际上希望排除这些东西,请事先将它们过滤掉:

const curriculum: Observable<Fichero>[] = usuario.curriculum.filter(f => !!f.awsKey).map(fichero => this.ficheroService.processFileUrl(fichero));

空值将阻止forkJoin发出,forkJoin中的所有可观察对象必须发出一个值并完成。