Abdul Pasaribu
Abdul Pasaribu

Reputation: 3

Outer observable never complete or finalized

I have two observables. How do I execute them sequentially and get the completed event one after another? I've tried concatMap, but it seems didn't work as I expected.

    this._activatedRouteService.queryParams
      .pipe(
        concatMap((params) => {
          console.log('start');
          if (typeof params['q'] === 'string') this._searchQuery = params['q'];
          else this._searchQuery = null;

          return this._postService
            .searchPosts(this._searchQuery!)
            .pipe(finalize(() => console.log('inner finalize')));
        }),
        finalize(() => {
          console.log('outer finalize');
        })
      )
      .subscribe(
        (response) => {
          this._posts = response?.data ?? this._posts;
        },
        (error) => {
          if (error instanceof HttpErrorResponse) {
            this._snackBarService.open(
              'Failed to fetch posts.\n' +
                (error.error?.message ?? 'Unknown error.'),
              undefined,
              {
                duration: SnackBarConfig.ERROR_DURATIONS,
              }
            );
          } else {
            this._snackBarService.open(
              'Failed to fetch posts.\nUnknown error.',
              undefined,
              {
                duration: SnackBarConfig.ERROR_DURATIONS,
              }
            );
          }
        },
        () => {
          console.log('outer complete');
        }
      );

But outer finalize or outer complete is never called.

Upvotes: 0

Views: 53

Answers (1)

Joshua McCarthy
Joshua McCarthy

Reputation: 1852

The reason outer finalize is never logged is that _activatedRouteService.queryParams never completes. It's a hot observable.

If you want the observable to complete after you execute the inner observable once, I recommend the take() operator. It will "take" any number of values emitted from the observable before sending a complete signal.

Try adding take(1), on the line before your concatMap().

Upvotes: 1

Related Questions