1
votes

I will preface this question by mentioning that I am new to both React and Redux...

I am working with example #14 from the BotFramework-WebChat samples.

https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/14.customization-piping-to-redux

In addition, to piping the Redux action activities to change the UI, I would also like to include middleware that listens for 'DIRECT_LINE/CONNECT_FULFILLED' and then dispatches 'WEB_CHAT/SEND_EVENT' with the 'webchat/join' payload so that I can display a welcome message.

I tried just modifying dispatchIncomingActivityMiddleware.js to look like the following:

export default function (dispatch) {
  return () => next => action => {
    if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
      const { activity } = action.payload;
      if (
        activity.type === 'event'
        && activity.from.role === 'bot'
        && activity.name === 'redux action'
      ) {
        dispatch(activity.value);
      }
    } else if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        dispatch({
          type: 'WEB_CHAT/SEND_EVENT',
          payload: {
            name: 'webchat/join',
            value: {
              language: window.navigator.language
            }
          }
        });
    } 

    return next(action);
  };
}

Needless to say, it doesn't work. I think this is because now all of the actions are being dispatched to the second app Redux store and not the Web Chat Redux store. My question is, how do I make it do both? Is there a way to dispatch certain actions to the app Redux store and other actions to the Web Chat store? Is there another way to achieve this?

2
Marking the solution as accepted serves the greater Stack Overflow community and anyone with a similar question. If you feel my answer was sufficient, please "accept" it. If not, let me know how else I can help!tdurnford

2 Answers

1
votes

An object with two properties - dispatch and getState - gets passed to the store middleware. You should either access the dispatch property from the incoming object or deconstruct it in the function header. Try:

export default function ({ dispatch }) {
    return ....
}

Also, the welcome message behavior in Web Chat has slightly changed. Take a look at this for more details.

0
votes

@tdurnford thanks for your response. I was able to finally get this to work by adding the following to WebChat.js:

constructor(props) {
    super(props);

    this.store = createStore(
      {},
      ({ dispatch }) => next => action => {
        if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
            dispatch({
              type: 'WEB_CHAT/SEND_EVENT',
              payload: {
                name: 'webchat/join',
                value: {
                  language: window.navigator.language
                }
              }
            });
        } 

        return next(action);
      },
      dispatchIncomingActivityMiddleware(props.appDispatch)
    );

    this.state = {};
  }

Now I am able to have actions dispatched to both the Web Chat redux store and the second custom redux store. Yay! The question I still have is, can you explain the difference between {dispatch} and props.appDispatch in this example? The latter seems to be passed through from the original declaration in index.js:

ReactDOM.render(
  <Provider store={ store }>
    <App />
  </Provider>,
  document.getElementById('root')
);

but what is {dispatch} referring to exactly in WebChat.js?