0
votes

I am developing a react/redux app that handles event registrations and have to develop an epic that is going to enrol users in different events.

There is currently an epic that handles the process of checking for available seats and I need to perform this action right before I run the "enrol" function.

So I've tried implementing an epic that would do the following:

 - Upon recieving an enrolInEvent.request it is going to then
 - Dispatch checkAvailableSeats.request action
 - Wait for checkAvailableSeats.success action
 - Run the 'enrol' async function
 - Dispatch checkAvailableSeats.request again
 - When it gets the checkAvailableSeats.success it is then mapped to enrolInEvent.success

Here's the code i've build, but I can't seem to find a way to dispatch the 'checkAvailableSeats.request' in the middle of the Epic. What is going on is the enrolInEvent.request is getting dispatched but then no new actions pop up in the redux-logger.

// tl;dr:
// enrolInEvent.request -> checkAvailableSeats -> enrol -> checkAvailableSeats again -> enrolInEvent.success

export const enrolInEventEpic: EventMetadataEpic =
  (action$, state$, { eventService }) =>
    action$.pipe(
      filter(isActionOf(enrolInEvent.request)),
      map(checkAvailableSeats.request), // I would need to dispatch this
      switchMap(() =>
        action$.pipe(  // Then scan the action observable for a success response
          filter(isActionOf(checkAvailableSeats.success)),
          take(1),
          switchMap(() =>
            from(eventService.enrolInCurrentEvent(
              state$.value.eventForm.eventStatus,
              state$.value.infrastructure.pageId,
            ))
            .pipe(
              map(checkAvailableSeats.request), // And dispatch here again
              switchMap(() =>
                action$.pipe(
                  filter(isActionOf(checkAvailableSeats.success)),
                  take(1),
                  map(checkStatus => enrolInEvent.success(checkStatus.payload)),
                  catchError((message: string) => of(enrolInEvent.failure(message))),
                )
              )
            )
          )
        )
      )
    );

I was under the impression that mapping to an action in the middle of the epic would dispatch it, but this is not true it seems. What's the simplest way to achieve the behaviour I need using the redux-observable?

1

1 Answers

2
votes

The only time when actions are dispatched is when the epic itself returns those actions, so map(checkAvailableSeats.request) is not going to work as you expect unless it is the last part of the epic.

I'm not really sure why you need checkAvailableSeats twice, but the two options I see are:

1) Inline the XHR logic in for checkAvailableSeats.request, maybe with an Ajax Observable. This way you don't have to dispatch the intermediate Redux action

2) Split your epic (enrolInEventEpic) so all actions are dispatched from separate epics and control which of the two request/success pairs is executing through differentiating action payload