Wrapping rxjs observable to do something before and after (for example show/hide loading screen)

Viewed 298

I am trying to create function which wraps given Observable and adds loading screen to it.
The function function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> should work like :

  1. show loading screen.
  2. execute observable received as parameter
  3. hide loading screen after all values are emitted.

My initial idea of implementation was:

function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => console.log("show loading screen")),
    switchMap(() => obs$),
    finalize(() => console.log("hide loading screen"))
  );
}

but when i chain other operators to result of this function then "hide loading screen" is executed after those chains (not after original observable finishing).

Here is an example: https://stackblitz.com/edit/rxjs-wrapping-observable

the result in console of above is

show loading screen
im reducing
im reducing
reducing finished so loading screen should be hidden
the result is 6
hide loading screen

what im aiming for should be

show loading screen
im reducing
im reducing
hide loading screen
reducing finished so loading screen should be hidden
the result is 6
1 Answers

That's because finalize is executed after the teardown, see this GitHub Issue for more info. That means that even though you are using finalize in the middle of the chain, even before the reduce and mergeMap, it will be executed last during the teardown process.

As for the alternative solution for your problem, you can use tap like so:

function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => console.log("show loading screen")),
    switchMap(() => obs$),
    tap(
      () => {},
      () => console.log("hide loading screen"),
      () => console.log("hide loading screen")
    ),
  );
}

Besides the next callback, you can provide the error and complete callbacks to the tap operator. See RxJS Tap Doc for more info about the error and complete callbacks.

Related