如何链接这些方法?

时间:2019-04-08 12:31:33

标签: angular rxjs

我创建了一个服务方法,可以检查数据库中是否存在给定的公司ID ...此方法很简单,返回true或false:

    public checkIfOndernemingsnummerAlreadyExists(ondernemingsnummer: string): Observable<boolean> {
        const url = `${environment.apiUrl}/ondernemingen/exists/${ondernemingsnummer}`;
        return this.http.get<boolean>(url);
    }

现在,我创建了一种向导,用户可以在特定步骤中创建新公司。

第一步,用户必须输入公司的ID号。 进行下一步时,我想检查数据库中是否已经存在该给定的ID号。

如果不存在,则用户可以继续执行向导中的下一步。 如果确实存在,则应显示警告消息,并且用户应停留在当前向导步骤。

因此,我在第一步中提交公司ID时添加了以下代码:

public submitOnderneming(): void {
    this.loading = false;
    this.isDuplicate = false;

    of(true).pipe(
      tap(() => this.loading = true),
      switchMap(() => this.kandidatuurService.checkIfOndernemingsnummerAlreadyExists(this.onderneming.ondernemingsnummer)),
      tap((res) => { this.isDuplicate = res; }),
      switchMap(() => { if (this.isDuplicate !== true) { return this.requestService.selectOnderneming(this.onderneming); }})
    ).subscribe(v => { this.loading = false; this.ref.detectChanges(); });
  }

但这给了我以下错误:

  

您在期望流的位置提供了“未定义”。您可以提供一个Observable,Promise,Array或Iterable。

现在我想是因为在第二个switchMap中,当isDuplicate不为true时,我仅返回一个值。在其他情况下,我什么也没退。

我的requestService.selectOnderneming看起来像这样:

    public selectOnderneming(onderneming: OndernemingDetail): Observable<RequestSteps> {
        this.store.dispatch(new SetOndernemingOfRequest(onderneming));
        return this.gotoNextStep();
    }

那么当isDuplicate为true时,应该在switchMap中写些什么? 还是应该完全重新排列我的代码?

我想要实现的是:

  1. 将loading属性设置为true
  2. 致电kandidatuurService.checkIfOndernemingsnummerAlreadyExists
  3. 根据此结果设置isDuplicate属性
  4. 不是重复调用requestService.selectOnderneming
  5. 全部完成后,将loading属性设置为false

3 个答案:

答案 0 :(得分:1)

Maybe there is a better solution, but for a hopefully working version:

this.loading = true;
this.kandidatuurService.checkIfOndernemingsnummerAlreadyExists(this.onderneming.ondernemingsnummer)
 .pipe(tap((isDuplicate) => this.isDuplicate = isDuplicate),
       switchMap((isDuplicate) => (isDuplicate ? of(true) : this.requestService.selectOnderneming(this.onderneming))))
 .subscribe(v => { this.loading = false; this.ref.detectChanges(); });

答案 1 :(得分:0)

不需要两个switchMap,反应式历史记录从第一个请求开始,您可以使其成为链的开始。过滤出重复的响应,然后切换到Map,应该就是这样。

编辑:如下所述,filter在返回false时应注意loading标志,因为没有其他人有机会。

this.loading = true;

this.kandidatuurService.checkIfOndernemingsnummerAlreadyExists(this.onderneming.ondernemingsnummer)
    .pipe(
        filter(
            //... logic checking for duplicates here
        ),
        switchMap(() => this.requestService.selectOnderneming(this.onderneming))
    )
    .subscribe( // subscribers here

答案 2 :(得分:0)

Ok, i implemented the suggestion as follows:

    this.loading = true;

    this.kandidatuurService.checkIfOndernemingsnummerAlreadyExists(this.onderneming.ondernemingsnummer)
      .pipe(
        tap((isDuplicate) => this.isDuplicate = isDuplicate),
        filter(x => x !== true),
        switchMap(() => this.requestService.selectOnderneming(this.onderneming))
      ).subscribe(v => { this.loading = false; this.ref.detectChanges(); });

but now the final subscribe is not being executed when it is a duplicate... Thats not really what i wanted...