How to group requests in redux-saga

Viewed 303

I need to load data for multiple charts. I also want to send the request only when chart settings change (distinctUntilChanged) and drop older requests (that do not reflect the current settings anymore - that's what the switchMap does). In rxjs and redux-observable, it would look like this:

export const chartsEpic = action$ =>
  action$
    .ofType('CHART_DATA_REQUESTED')
    // group actions by chart id...
    .groupBy(action => action.meta.chartId)
    // ...and for each chart:
    .map(actionsByChart$ =>
      actionsByChart$
        // continue only if settings change
        .distinctUntilChanged((a1, a2) => compare(a1.payload.settings, a2.payload.settings))
        // load data, but drop old requests when we get new settings
        .switchMap(action => 
          Observable.fromPromise(fetchChartData(action.payload.settings))
            .map(data => ({type: 'CHART_DATA.SUCCESS', payload: data, meta: action.meta))
            .catch(error => Observable.of({type: 'CHART_DATA.FAILURE', payload: error, meta: action.meta}))
        )
    )
    // combine actions for all charts into one output stream
    .mergeAll();

What is the comparable code in redux-saga?

1 Answers

The generic way to achieve it:

function* syncChartsFlow(){
     var fetchTask = null;
     while(true){
          yield take([INITIAL_FETCH, SETTINGS_CHANGED])
          if(fetchTask){
              yield cancel(fetchTask)
          }
          fetchTask = yield fork(fetchChartsInfo)
     }
}

function* fetchChartsInfo(){
  // fetch info here
}
Related