2

Lets say I have an angular http Observable.

I'm not sure is it going to resolve after 100ms or 5 seconds and I would like to trigger a loading spinner if the delay is more than a second.

Is someone know an elegant way to do that?

I was thinking that there is some handy RxJS operator for that, but I couldn't find such.

Thanks

Kaloyan Stamatov
  • 3,894
  • 1
  • 20
  • 30

1 Answers1

3

You can just merge the HTTP request and a delayed emission you'll ignore:

merge(
  makeHTTPRequest(),
  timer(1000).pipe(
    tap(() => {/* show loading spinner */}),
    ignoreElements(),
  )
)
  .pipe(take(1))
  .subscribe();

Note, that in this case I had to include take(1) so the chain will complete when makeHTTPRequest() emits and won't wait for both Observables to complete.

martin
  • 93,354
  • 25
  • 191
  • 226
  • From what I've read the ignoreElements passes calls of complete or error. Why after 1000ms the timer does not complete? – Kaloyan Stamatov Jun 15 '23 at 11:21
  • `merge` completes only when all its source Observables complete. `timer()` does complete but if the `makeHTTPRequest` would complete before 1000ms the chain would complete after 1000ms anyway. – martin Jun 15 '23 at 12:19
  • I see, is it possible if the makeHTTPRequest() completes for 100ms not to wait 1 second for the timer? – Kaloyan Stamatov Jun 16 '23 at 06:01
  • That's what `take(1)` does. – martin Jun 16 '23 at 08:23
  • Sorry you lose me here. You point that the merge completes only when all its source Observables complete. So how when makeHTTPRequest completes and timer does not, the take(1) will handle the job. And how if timer completes we will still wait for the makeHTTPRequest()? – Kaloyan Stamatov Jun 16 '23 at 09:11