Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I delay an observable only if it returns faster than the delay

Take for example:

 this.http.get('/getdata').pipe(delay(2000))

I would like this request to take a minimum of 2s to complete, but not any longer than it takes for the request to complete.

In other words:

  1. if the request takes 1s to complete, I want the observable to complete in 2s.

  2. if the request takes 3s to complete, I want the observable to complete in 3s NOT 5s.

Is there some other pipe other than delay() that can achieve this that I don't know about or is there a way to build a custom pipe for this if necessary?

The use case is to show a loader, however if the request completes too fast it doesnt look good when the loader just "flashes" for a split second

like image 761
parliament Avatar asked Jan 03 '19 22:01

parliament


People also ask

How do you delay an Observable?

The Delay operator modifies its source Observable by pausing for a particular increment of time (that you specify) before emitting each of the source Observable's items. This has the effect of shifting the entire sequence of items emitted by the Observable forward in time by that specified increment.

Why Observable is lazy?

Observables are "lazy", meaning if no one is listening, nothing happens.

What is pipe operator in RXJS?

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable. It is a pure operation: the previous Observable stays unmodified. A Pipeable Operator is essentially a pure function which takes one Observable as input and generates another Observable as output.

What is from in RXJS?

from converts various other objects and data types into Observables. It also converts a Promise, an array-like, or an iterable object into an Observable that emits the items in that promise, array, or iterable. A String, in this context, is treated as an array of characters.


1 Answers

To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.

combineLatest(this.http.get('/getdata'), timer(2000), x => x)
like image 198
GregL Avatar answered Oct 03 '22 03:10

GregL