androbin
androbin

Reputation: 1759

RxJS distinct throttleTimer

I would like to have a observable that fires when a distinct change was made or an interval hits.

The use-case is I would like to load a http request whenever the selected entity is changed, but over a specified time it should be reloaded.

A: user select entity on each route change.

B: Interval.

C: Expected output.

A: --2--2--2--2--2--2--2--3--3--3--2--2--2--2--2--
B: --------1--------2--------3--------4--------5--
C: --2-----2--------2-----3--3-----2--2--------2-- 

I tried many ways, but none of them working. All the combinations of throttleTime and distinct I could think of with external variables.

EDIT:

One another case that shows C does not have to be triggered, as being a http request.

A: --2--2--------------2--3--3-----------2--------
B: --------1--------2--------3--------4--------5--
C: --2-----------------2--3--3-----------2-------- 

Output of C:

2: triggered as A wants to run the http request.
-: not triggered as it is too close (in time) to request before.
-: just the timer ticks.
-: just the timer ticks.
2: triggered as being far away from (in time) the request before.
3: triggered as different id for the http request.
3: triggered as the timer ticked and http request can be sent.
-: just the timer ticks.
2: loaded
-: just the timer ticks.

Upvotes: 1

Views: 220

Answers (2)

androbin
androbin

Reputation: 1759

The withLatestFrom is the proper way to connect data from an obervavble without subscribing to its triggers.

The working piece of code:

loadTimer = timer(0, 60000); //b$
c$ = a$.pipe(
  withLatestFrom(this.loadTimer, (action, timerValue) => ({ action, timerValue })),
  distinctUntilChanged((a, b) => a.action.payload === b.action.payload && a.timerValue === b.timerValue),
  tap(a => console.log(a)),
  map(a => a.action),
  exhaustMap(action =>
    this.businessLoaderService
      .load(action.payload)
      ...
  )

Upvotes: 0

martin
martin

Reputation: 96889

I think you could do it using the combineLatest operator

const $b = Observable.timer(0, xyz);

$c = a$
  .distinctUntilChanged()
  .combineLatest($b, val => val);

It doesn't seem like you really need to use any throttleTime

Upvotes: 2

Related Questions