Redux-observable: react-router-redux push function not working from epic ?

Created on 24 Aug 2017  路  6Comments  路  Source: redux-observable/redux-observable

Hi guys,

Thanks for this powerful middleware.

I am trying to push new route from epic function using push function of react-router-redux but seems push is not firing!

    import * as ajax from '../../utils/ajax';

    import {
        FETCH_PRODUCTS_REQUEST,
    }  from '../actions/actionTypes';

    import { doFetchProductsFulfilled } from '../actions/doFetchProducts';
    import { push } from 'react-router-redux';

    export default function epicFetchProducts(action$, store, { queryString }) {
        return action$.ofType(FETCH_PRODUCTS_REQUEST)
            .map(function(action){
                store.dispatch(
                    push('/fooo' )
                )
                const searchString = queryString.stringify(action.atts)
                return Object.assign({}, action, {
                    searchString
                })

            })
            .mergeMap(action =>
                ajax.get(`/products?${action.searchString}`)
              .map(response => doFetchProductsFulfilled(response))
            );
    }



Here is my module versions -

  • "history": "^4.6.3"
  • "react-redux": "^5.0.5"
  • "react-router": "^4.1.2"
  • "react-router-dom": "^4.1.2"
  • "react-router-redux": "^5.0.0-alpha.6"

Is there any guideline/implementations for this ?

Thank you in advance!

Most helpful comment

I had a similar issue today. I noticed it was my configuration issue with react-router-redux 5.x (used with react-router 4.x).

Pay close attention to README's usage guide. Key things to lookout are (see the README's code for details):

  • Combine routerReducer with a key of router when creating the store.
  • Apply routerMiddleware when creating the store (I forgot this).

Once that is done, you should be able to navigate to another route by calling push from an epic like this:

action$ => action$
  .ofType('myActionType')
  .mapTo(push('/my-route'))

Notice that I call push() (this function returns RouterAction) within mapTo(). This is to avoid dispatching from within the epic (i.e. anti-pattern mentioned above).

All 6 comments

hmm could you describe what you mean by "not firing"? Can you reproduce this using jsbin, repo, or similar I can test? I and many others use react-router-redux without issue so my first hunch is a configuration issue for your store/middleware/reducers. Have you doubled checked how you're providing routerMiddleware, routerReducer, and ConnectedRouter?

btw using store.dispatch in your epics is discouraged, especially inside a map. We're almost certainly going to remove that ability soon.

Using store.dispatch() inside your Epic is a handy escape hatch for quick hacks, but use it sparingly. It's considered an anti-pattern and we may remove it from future releases. -Docs

Closing as I'm pretty confident this is not a bug with redux-observable and we ask users use Stack Overflow for support questions.

That said, if you can provide me a way to reproduce this easily I'm happy to take a quick look. 馃槃

I had a similar issue today. I noticed it was my configuration issue with react-router-redux 5.x (used with react-router 4.x).

Pay close attention to README's usage guide. Key things to lookout are (see the README's code for details):

  • Combine routerReducer with a key of router when creating the store.
  • Apply routerMiddleware when creating the store (I forgot this).

Once that is done, you should be able to navigate to another route by calling push from an epic like this:

action$ => action$
  .ofType('myActionType')
  .mapTo(push('/my-route'))

Notice that I call push() (this function returns RouterAction) within mapTo(). This is to avoid dispatching from within the epic (i.e. anti-pattern mentioned above).

@kctang 馃嵕 thank you for adding your findings!! 鉁岋笍

For anyone struggling with this, I had a similar problem when calling the push method from within an epic. I could see the action 'router/CALL_HISTORY_METHOD' in redux dev tools but the actual URL wasn't being changed. The problem simply was that middlewares were being applied to the redux store in the wrong order.
This is the working store configuration

import { applyMiddleware, compose, createStore } from 'redux'
import { createEpicMiddleware } from 'redux-observable'
import { routerMiddleware } from 'react-router-redux'
import history from './history'
import rootEpic from '../epics'

let middlewares = []

middlewares.push(applyMiddleware(createEpicMiddleware(rootEpic)))
middlewares.push(applyMiddleware(routerMiddleware(history)))

createStore(rootReducer, undefined, compose(...middlewares))
Was this page helpful?
0 / 5 - 0 ratings