I am currently setting up an epic that listens to the action of type LOCATION_CHANGE
or LocationChangeAction
, which is an action that is triggered whenever the router history changes due to router actions such as push
or replace
.
import { LOCATION_CHANGE, LocationChangeAction } from 'connected-react-router';
import { isActionOf } from 'typesafe-actions';
const locationEpic: Epic = (action$) => action$.pipe(
filter(isActionOf(LocationChangeAction)),
tap((action) => {
// do the rest here
})
);
However, doing the above will throw the error, and adding typeof
does not seem to help either.
'LocationChangeAction' only refers to a type, but is being used as a value here.
May I know what is the proper way of doing it, by using typesafe-actions
's isActionOf()
operator?
Referring to
Argument contains array with invalid element at index 0, it should be an action-creator instance from "typesafe-actions"
It might throw that error because ActionCreator
contains ActionCreatorTypeMetadata which requires getType?: () => TType
:
type TypeConstant = string;
export interface ActionCreatorTypeMetadata<TType extends TypeConstant> {
getType?: () => TType;
}
ActionCreator
export type ActionCreator<T extends { type: string }> = ((
...args: any[]
) => T) &
ActionCreatorTypeMetadata<T['type']>;
But, the onLocationChanged
function implements only the first part of the intersection(a function that returns an object that has a property type
).
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'
export const onLocationChanged = (location, action, isFirstRendering = false) => ({
type: LOCATION_CHANGE,
payload: {
location,
action,
isFirstRendering,
}
})
The function must also contain a property getType
:
onLocationChanged.getType = () => `YOUR_TYPE`.
For those who are using typesafe-actions
, you will need to register the LOCATION_CHANGE
action,
import { LOCATION_CHANGE, RouterActionType } from 'connected-react-router';
import { Location } from 'history';
import { createAction } from 'typesafe-actions';
namespace RouterActions {
export const onLocationChanged = createAction(
LOCATION_CHANGE,
(action) => (location: Location, routerAction: RouterActionType, isFirstRendering?: boolean) => action({
location,
action: routerAction,
isFirstRendering,
}),
);
}
export default RouterActions;
And on your epics, you can simply listen to the LOCATION_CHANGE
action,
const locationEpic: Epic = (action$) => action$.pipe(
filter(isActionOf(RouterActions.onLocationChanged)),
switchMap((epic) => {
// do the rest
}),
);