Rx : Force observable to take at least N seconds to complete

Viewed 1761

I am making a splash screen for my app. I want it to last at least N seconds before going to the main screen.

I have an Rx variable myObservable that returns data from the server or from my local cache. How do I force myObservable to complete in at least N seconds?

myObservable
// .doStuff to make it last at least N seconds
   .subscribe(...)
2 Answers

You can use forkJoin to wait until two Observables complete:

Observable.forkJoin(myObservable, Observable.timer(N), data => data)
  .subscribe(...);

For RxJS 6 without the deprecated result selector function:

forkJoin(myObservable, Observable.timer(N)).pipe(
  map(([data]) => data),
)
.subscribe(...);

Edit: As mentioned in comments, Observable.timer(N) with just one parameter will complete after emitting one item so there's not need to use take(1).

Angular 7+ example of forkjoin

I like to build in a higher delay on my development system since I assume production will be slower. Observable.timer doesn't seem to be available any longer but you can use timer directly.

forkJoin(

  // any observable such as your service that handles server coms
  myObservable,

  // or http will work like this
  // this.http.get( this.url ),

  // tune values for your app so very quick loads don't look strange
  timer( environment.production ? 133 : 667 ),

).subscribe( ( response: any ) => {

  // since we aren't remapping the response you could have multiple
  // and access them in order as an array
  this.dataset = response[0] || [];

  // the delay is only really useful if some visual state is changing once loaded
  this.loading = false;

});
Related