How to debounce by ID in RxJS

Viewed 259

My problem is the next: I want to debounce the liking functionality of my app. I using actions to make changes in my app, for example:

dispatch(likePost(1)) // => dispatch({ type: 'LIKE_POST', id: 1 })

Given the next example:

I dispatch an action at time: 0

dispatch(likePost(1))

This gonna trigger my actionSource:

actionSource$.
   pipe(
      filter(isActionOf(likePost)),
      debounceTime(500)
      mapTo('make-api-request-to-like-the-post')
   )

So it's gonna looks like:

--DISPATCH(LIKE(1))---DEBOUNCE(500)---MAKE_API_CALL(1)---->

But there is a problem with this, as what happens if I make the next actions:

dispatch(likePost(1)) // at time 0ms
dispatch(likePost(2)) // at time 200ms

here we got a problem as the likePost(2) debounced the likePost(1), resulting only making a request with the likePost(2)

--DISPATCH(LIKE(1))--200ms--DISPATCH(LIKE(2))--DEBOUNCE(500)--MAKE_API_CALL(2)--->

So how could I debounce by id, or make it unique branches by id.

1 Answers

You can groupBy events by id and then apply debounceTime on each group individually.

For example:

const { of } = rxjs; // = require("rxjs")
const { map, mergeMap, groupBy, debounceTime } = rxjs.operators; // = require("rxjs/operators")

of(1, 1, 2, 3, 1, 1).pipe(
  groupBy(id => id),
  mergeMap(likeById$ => 
    likeById$.pipe(
      debounceTime(500)
    )
  )
).subscribe(e => console.log(e));
<script src="https://unpkg.com/rxjs@6.5.3/bundles/rxjs.umd.min.js"></script>

Related