Комбинированный наблюдаемый не выполняет HTTP-вызов

#javascript #angular #rxjs

#javascript #угловой #rxjs

Вопрос:

У меня есть служба с 3 общедоступными методами. Они зависят от результата this.dossierService.dossierIds . dossierIds является получателем, который возвращает BehaviorSubject<DossierIds[]> .

  public createObligation(id: string): Observable<void> {
    return this.getObligationsUrl(id).pipe(
      map(dossierIds => {
        const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla}`;
        return this.http.post(endpoint);
      })
    );
  }


  public deleteMortgageObligation(id: string): Observable<void> {
    return this.getObligationsUrl(id).pipe(
      map(dossierIds => {
        const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
        return this.http.delete(endpoint);
      })
    );
  }

  public updateObligation(id: string): Observable<void> {
    //..
  }

  private getObligationsUrl(dossierIds: DossierIds): string {
    return this.dossierService.dossierIds.pipe(
      map(dossierIds => {
        const dossierId = dossierIds.getDossierId();
        const moId = dossierIds.getObligationsId();
        return `${BASE_URL}/${dossierId}/${OBLIGATIONS_URL}/${moId}`;
      }),
    );
  }
  

Эти методы будут использоваться в компоненте, подобном этому

 this.createObligation(123).subscribe(result => {
  console.log(result);
})
  

Но TypeScript выдает мне ошибку во всех 3 методах, говоря:

 Type 'Observable<Observable<void>>' is not assignable to type 'Observable<void>'Type 'Observable<void>' is not assignable to type 'void'.
  

И я даже не вижу, что мои HTTP-запросы запускаются. Где я допустил ошибку?

Ответ №1:

Причина, по которой http-вызов не выполняется, заключается в том, что вы не подписываетесь на внутренний наблюдаемый.

 1   public deleteMortgageObligation(id: string): Observable<void> {
2     return this.getObligationsUrl(id).pipe(
3       map(dossierIds => {
4         const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
5         return this.http.delete(endpoint);
6       })
7     );
8   }
  

В строке # 5 вы возвращаете observable, но на него никогда не подписывается. Таким образом, возвращается строка # 2 Observable<Observable<>> . Вам необходимо убедиться, что на этот внутренний наблюдаемый подписан и что его результат передается через поток.

Это именно то, для чего предназначены «Операторы сопоставления более высокого порядка«. Они выполняют следующее:

  1. сопоставляет входящее значение с другим наблюдаемым
  2. подписывается на него, поэтому его значения передаются в поток
  3. управляет отменой подписки на эти «внутренние подписки»

В вашем случае мы можем просто использовать switchMap on line # 3 вместо map :

 1   public deleteMortgageObligation(id: string): Observable<void> {
2     return this.getObligationsUrl(id).pipe(
3       switchMap(dossierIds => {
4         const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
5         return this.http.delete(endpoint);
6       })
7     );
8   }