[RxJS] Groupby operator

The use case is similar to Twitter "like" button, you can click "click" button on different post, each "like" button are isolated, it preforms optimistic UI render, handling the back-press on backend, cancel previous request only for the same twitter id.

In the talk of RxJS. It use Movie as example.

So, if you have similar use case, this piece of code can help:

import { Observable, fromEvent, Subject, EMPTY } from 'rxjs';
import { tap, mergeMap, groupBy, timeoutWith, ignoreElements, switchMap } from 'rxjs/operators';

const actions$ = dispatcher.asObservable().pipe(
  // optimize ui rendering
  tap(({ movieId }) => setButtonEmoji(movieId)),
  // group all the request by movieId
  groupBy(
    movie => movie.movieId,
    movie => movie,
    // cancel the extra requests to prevent memory leak by set 15s idel time
    actionsByGroup$ =>
      actionsByGroup$.pipe( 
        timeoutWith(15000, EMPTY),
        ignoreElements()
      )
  ),
  // for each group of request, we apply switchMap to cancel previous request
  // finally flatten the requests into one
  mergeMap(group$ => group$.pipe(switchMap(movie => toggleStatus(movie.movieId))))
);