I am the registerEpic utility described here: Is it efficient to use the deceitfulness of new epics inside onEnter reaction routers?
Our code should be isomorphic, but on the server side the action is launched for the first time, and everything is fine. However, the second time the action fires, the epic seems to get 2 copies of this action. Here is my code:
export const fetchEpic = (action$, store) =>
action$.ofType("FETCH")
.do((action) => console.log('doing fetch', action.payload))
.mergeMap(({meta:{type}, payload:[url, options = {}]}) => {
let defaultHeaders = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
options.headers = {...defaultHeaders, ...options.headers};
let request = {
url,
method: 'GET',
responseType: 'json',
...options
};
return AjaxObservable.create(request)
.takeUntil(action$.ofType(`${type}_CANCEL`))
.map(({response: payload}) => ({type, payload}))
.catch(({xhr:{response: payload}}) => (Observable.of({type, payload, error: true})));
}
);
registerEpic(fetchEpic);
so the first time I click on the page that launches this action (server side), everything works fine, and I get to "make a selection" once in the console.
However, when you refresh the page, you get 2 of these console messages, and the resulting actions do not start.
"" , , , Noob . :
let epicRegistry = [];
let mw = null;
let epic$ = null;
export const registerEpic = (epic) => {
if (epicRegistry.indexOf(epic) === -1) {
epicRegistry.push(epic);
if (epic$ !== null) {
epic$.next(epic);
}
}
};
export const unregisterEpic =(epic) => {
const index = epicRegistry.indexOf(epic);
if(index >= 0) {
epicRegistry.splice(index, 1);
}
}
export const clear = () => {
epic$.complete();
epic$ = new BehaviorSubject(combineEpics(...epicRegistry));
}
export default () => {
if (mw === null) {
epic$ = new BehaviorSubject(combineEpics(...epicRegistry));
const rootEpic = (action$, store) =>
epic$.mergeMap(epic => epic(action$, store));
mw = createEpicMiddleware(rootEpic);
}
return mw;
};