piotrwitek / typesafe-actions

Typesafe utilities for "action-creators" in Redux / Flux Architecture
https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox
MIT License
2.41k stars 98 forks source link

How to handle filtering in epic with more than one action? #27

Closed kralcifer-ms closed 6 years ago

kralcifer-ms commented 6 years ago

In the following code snippet it lets 2 actions in but then TypeScript complains trying to access payload on clearVisitedStream because authLogoutSuccess action is a simple action without a payload.

export const authLogoutSuccess = buildAction('AUTH_LOGOUT_SUCCESS').empty();
export const clearVisitedStream = buildAction('CLEAR_VISITED_STREAM').fsa((channelId?: number) => ({ channelId }));

const clearChannelVisitHistory: Epic<RootAction, IRootState> = action$ =>
    action$
        .filter(isActionOf([clearVisitedStream, authLogoutSuccess]))
        .mergeMap(action => {
            if (isActionOf(authLogoutSuccess) || (isActionOf(clearVisitedStream) && action.payload.channelId === null)) {

gives typescript error:

Property 'payload' does not exist on type 'EmptyAction<"AUTH_LOGOUT_SUCCESS"> | PayloadAction<"CLEAR_VISITED_STREAM", { channelId: number; }>'. Property 'payload' does not exist on type 'EmptyAction<"AUTH_LOGOUT_SUCCESS">'.

piotrwitek commented 6 years ago

isActionOf is higher order function, think "ramda" way, you should do isActionOf(authLogoutSuccess)(action), but I would use switch case instead, we do it like in reducer switch case:

action$
    .map(action => {
      switch (action.type) {
        case getType(shipmentsActions.getShipmentListSuccess):
          return deliveriesActions.getShipmentListStatusesRequest(
            action.payload.shipments.map(s => s.id)
          );
        case getType(shipmentsActions.getShipmentRequest):
          return deliveriesActions.getShipmentStatusesRequest
...