redux-observable multiple actions after 1st dispatch
<p>I'm the 'registerEpic' utility described here: <a href="https://stackoverflow.com/questions/40202074/is-it-an-efficient-practice-to-add-new-epics-lazily-inside-react-router-onenter">Is it an efficient practice to add new epics lazily inside react-router onEnter hooks?</a></p>

<p>Our code needs to be isomoprhic, but on the server side, an action is triggered the 1st time and all is well.  However the 2nd time the action is triggered, the epic seems to get 2 copies of that action.  Here's my code:</p>

<pre><code>export const fetchEpic = (action$, store) =&gt;
  action$.ofType("FETCH")
    .do((action) =&gt; console.log('doing fetch', action.payload))
    .mergeMap(({meta:{type}, payload:[url, options = {}]}) =&gt; {

            let defaultHeaders = {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            };

            options.headers = {...defaultHeaders, ...options.headers};

            let request = {
                url,
                method: 'GET',
                responseType: 'json',
                ...options
            };

            //AjaxObservables are cancellable... that's why we use them instead of fetch.  Promises can't be cancelled.

            return AjaxObservable.create(request)
                .takeUntil(action$.ofType(`${type}_CANCEL`))

                .map(({response: payload}) =&gt; ({type, payload}))
                .catch(({xhr:{response: payload}}) =&gt; (Observable.of({type, payload, error: true})));

        }
    );

 registerEpic(fetchEpic);
</code></pre>

<p>so the 1st time I hit a page which triggers this action (server side) everything works fine and i get the 'doing fetch' once in the console.</p>

<p>However, refreshing the page, yields 2 of those console messages and the resulting actions are not triggered.</p>

<p>I added a 'clear' function to my epic registry, but maybe I'm total noob sauce and just don't grok it fully.  Here's my middleware:</p>

<pre><code>let epicRegistry = [];
let mw = null;
let epic$ = null;
export const registerEpic = (epic) =&gt; {
    // don't add an epic that is already registered/running
    if (epicRegistry.indexOf(epic) === -1) {
        epicRegistry.push(epic);

        if (epic$ !== null) { //this prevents the observable from being used before the store is created.
            epic$.next(epic);
        }
    }
};

export const unregisterEpic =(epic) =&gt; {
    const index = epicRegistry.indexOf(epic);
    if(index &gt;= 0) {
        epicRegistry.splice(index, 1);
    }
}

export const clear = () =&gt; {
    epic$.complete();
    epic$ = new BehaviorSubject(combineEpics(...epicRegistry));

}

export default () =&gt; {

    if (mw === null) {
        epic$ = new BehaviorSubject(combineEpics(...epicRegistry));
        const rootEpic = (action$, store) =&gt;
            epic$.mergeMap(epic =&gt; epic(action$, store));

        mw = createEpicMiddleware(rootEpic);
    }

    return mw;
};
</code></pre>