最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

angular - RxJS complete Observable from within switchmap - Stack Overflow

programmeradmin2浏览0评论

I have an HTTP call that does a switchMap to a Promise<boolean>. If that promise returns false, I need it to close the observable. Here is some example code

private method2() : Observable<MyModel> {
      return this.service.httpCall().pipe(
            switchMap(
                async (model: MyModel) =>
                {
                    const navResult = await this.router.navigate(...);
                    // Navigation can still fail. This Observable hence should only complete when navigation completes
                    if (navResult)
                    {
                        return model;
                    }
                    // If navResult fails, I need this observable to close.
                    // Do I just not return anything? Leaving the subscriber waiting for ever? Or do I need to explicitly close it? If so, how?
                    // return EMPTY does not work because of the explicitly declared return type.
                }));


private method1()  {
  this.method2().pipe(tap((result) => {
      // Some logic which should only be called when the `navResult` inside the second method is `true`
    }), 
    catchError(error => {
      // Some logic which should only be called when `method2` throws an error
    });
}

But the problem now is that method2 is not closing the observable when navResult is false.

I have an HTTP call that does a switchMap to a Promise<boolean>. If that promise returns false, I need it to close the observable. Here is some example code

private method2() : Observable<MyModel> {
      return this.service.httpCall().pipe(
            switchMap(
                async (model: MyModel) =>
                {
                    const navResult = await this.router.navigate(...);
                    // Navigation can still fail. This Observable hence should only complete when navigation completes
                    if (navResult)
                    {
                        return model;
                    }
                    // If navResult fails, I need this observable to close.
                    // Do I just not return anything? Leaving the subscriber waiting for ever? Or do I need to explicitly close it? If so, how?
                    // return EMPTY does not work because of the explicitly declared return type.
                }));


private method1()  {
  this.method2().pipe(tap((result) => {
      // Some logic which should only be called when the `navResult` inside the second method is `true`
    }), 
    catchError(error => {
      // Some logic which should only be called when `method2` throws an error
    });
}

But the problem now is that method2 is not closing the observable when navResult is false.

Share edited Feb 6 at 10:58 Naren Murali 56.8k5 gold badges40 silver badges71 bronze badges asked Feb 6 at 10:44 Wouter VandenputteWouter Vandenputte 1258 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

You have 2 choices:

  • Either your inner observable throws on fail and you catch that in the subscribe
  • You filter after the switchMap to prevent the observable from emitting a value. (and it will complete because of the http request usually completes the observable).

Use from to convert the navigate promise to Observable.

Then use map to swap with model or just return false, either way you look at, it will complete, use the boolean, to either trigger further actions or stop the logic.

The HttpClient Observable completes after the data is fetched, so there is no need for EMPTY since it autocompletes is my point.

Http Observables

export class App {
  router = inject(Router);

  httpCall(): Observable<MyModel> {  
    return of({})
  }
  
  private method2() : Observable<MyModel | boolean> {
    return this.httpCall().pipe(
      switchMap((model: MyModel) => from(this.router.navigate(['../'])).pipe(
        map((navResult: boolean) => navResult ? model : false)
      )),
    );
  }

  private method1()  {
    this.method2().pipe(
      tap((result: any) => {
        // Some logic which should only be called when the `navResult` inside the second method is `true`
      }), 
      catchError((error: any) => {
        // Some logic which should only be called when `method2` throws an error
      })
    ).subscribe();
  }
}
发布评论

评论列表(0)

  1. 暂无评论