0
votes

I'm using React, Redux, Redux-Observable, rxjs and TypeScript. I have a epic which creates records. I want to dispatch an additional action from the epic.

export const createEpic: Epic = (action$) => action$.pipe(
    ofType(ITEMS_CREATE),
    mergeMap((action) => CoreCom.create<{Item: Item}>(
        '/items/index',
        {},
        'Item',
        action.item,
    ).pipe(
        map((response) => itemsCreateSuccess(response.response)),
        catchError(() => of(itemsCreateFailure())),
    )),
);
export const createSuccesEpic: Epic = (action$) => action$.pipe(
    ofType(ITEMS_CREATE_SUCCESS),
    map(
        () => enqueueSnackbar({
            message: 'Hello World!',
            options: {
                variant: 'success',
            },
        }),
    ),
);

The first epic reacts on action ITEMS_CREATE. Then it fires a call and gets back a server response. Then the action ITEMS_CREATE_SUCCESS is dispatched.
Additionally I want to dispatch an action to show a notification. I ended up with two epics.

Can somebody help me to "merge" this two epics into one? Or is this good as it is?

I wasn't able to dispatch two actions from the same epic.

EDIT:

FYI: the function itemsCreateSuccess(), itemsCreateSuccess() and enqueueSnackbar() are returning something similar to this:

export const itemsCreateSuccess = (response: Response): ItemsCreateSuccessAction => ({
    type: ITEMS_CREATE_SUCCESS,
    response,
});

they are just returning actions

1

1 Answers

0
votes

Your solution, in my opinion, has a good point which is the separation of concerns which can bring more flexibility to your code because later you can use this createSuccesEpic epic to show those success notifications for different "success actions" (as I do not know the context of your app is up to you to take that in consideration).

To your question about how you can dispatch those two actions from createEpic I see a solution using mergeMap and merge on your second pipe. So your code will look like this:

export const createEpic: Epic = (action$) => action$.pipe(
    ofType(ITEMS_CREATE),
    mergeMap((action) => CoreCom.create<{Item: Item}>(
        '/items/index',
        {},
        'Item',
        action.item,
    ).pipe(
        mergeMap(response => merge(
            of(itemsCreateSuccess(response.response)),
            of(enqueueSnackbar({ ... }))
        )),
        catchError(() => of(itemsCreateFailure())),
    )),
);