1
votes

I just started using Redux-Observable. I want to make a generic epic that requests data from the server. I want multiple requests with same action and id to be debounced. However, I'm not sure how to do this without creating multiple epics.

const TYPE_IFEXISTS_REQUEST = 'IFEXISTS_REQUEST';
export const IFEXISTS_REQUEST = (id, value) =>
  ({ type: TYPE_IFEXISTS_REQUEST, id, value });
export const IFEXISTS_EPIC = action$ =>
  action$
    .ofType(TYPE_IFEXISTS_REQUEST)
    .debounceTime(5000) // ERROR: debounces based on action type and not id
    .mergeMap(action =>
      fromPromise(api.get(`/api/exists/${action.id}/${action.value}`))
        .map(({ data }) => IFEXISTS_SUCCESS(action.id, data))
        .catch(() => of(IFEXISTS_FAILURE(action.id, 'Server error'))));

How is it possible to create a generic epic that debounces based on both action and id?


Update: Never knew about GroupBy. It worked well with switchMap. The following is was I used.

action$
    .ofType(TYPE_IFEXISTS_REQUEST)
    .groupBy(action => action.id)
    .mergeMap(actionByIdGroup$ => 
        actionByIdGroup$
            .debounceTime(5000) // debounces based on action id
            .switchMap(action =>
                fromPromise(api.get(`/api/exists/${action.id}/${action.value}`))
                    .map(({ data }) => IFEXISTS_SUCCESS(action.id, data))
                    .catch(() => of(IFEXISTS_FAILURE(action.id, 'Server error')))
            );
    )
1

1 Answers

3
votes

You can use the groupBy operator:

  action$
    .ofType(TYPE_IFEXISTS_REQUEST)
    .groupBy(action => action.id)
    .mergeMap(actionByIdGroup$ => 
        actionByIdGroup$
            .debounceTime(5000) // debounces based on action id
            .mergeMap(action =>
                fromPromise(api.get(`/api/exists/${action.id}/${action.value}`))
                    .map(({ data }) => IFEXISTS_SUCCESS(action.id, data))
                    .catch(() => of(IFEXISTS_FAILURE(action.id, 'Server error')))
            );
    )

The actionByIdGroup$ is a Grouped Observable of the same action ids. Meaning, only actions with the same id will be part of the same stream. In this case, the debounceTime will be applied for actions with the same id.