1
votes

I have an epic which dispatches an action that is handled by a redux middleware, which returns a promise once the action is dispatched. The epic looks approximately like this:

const myEpic = action$ =>
  action$.pipe(
    ofType(SAVE_ACTION),
    switchMap(action => [
      saveData(action.payload)
    ])
) 

When the SAVE_ACTION is dispatched, it is picked up by the epic, which dispatches an action created by the saveAction action creator.

This resulting action is intercepted by a redux middleware (specifically redux-axios-middleware) which does an HTTP request and converts the result of dispatching such action to a promise, which has the standard behavior of resolving when the HTTP request succeeds and rejecting when the HTTP request fails.

What I would need to do is do additional work once that promise is resolved, within this epic, because I need data contained both in the payload of the initial SAVE_ACTION action and the payload of the HTTP response.

Because the middleware also dispatches actions upon completion of the underlying HTTP request, it would be easy to write an additional epic to do the additional work I need to do in a distinct epic, but I wouldn't have access to the payload of the initial SAVE_ACTION anymore, so I'm trying to figure out if this can be handled all within a single epic, and I haven't found a way so far. I have found online posts like this one, which is very informative, but still doesn't address the issue of awaiting the dispatch of an action, rather than a plain observable.

1
Why would you have a second middleware to handle your Ajax call, why not handle them within redux-observable?Anas
You would have to ask the authors of the original code @Anas :) Let's just assume that there are more such epics than it's worth changing to use a different approach at triggering HTTP requestsSimone

1 Answers

0
votes

One approach would be to use merge like this:

 import { merge } from 'rxjs/observable/merge';

 const myEpic = action$ => {
     let initialPayload = null;      

     return merge(
         action$.pipe(
             ofType(SAVE_ACTION),
             switchMap(action => {
                 initialPayload = action.payload;

                 return [saveData(action.payload)]
             })
         ),

         action$.pipe(
             ofType(SAVE_ACTION_SUCCESS),
             mergeMap(action => {
                 // Use initialPayload here.
             })
         ),
    )
}