This code should work for you:
export const socketNewOrder = (order) => {
return {
type: 'SOCKET_NEW_ORDER',
payload: order
}
}
const handlerFunc = (dispatch) => (order) => {
dispatch(socketNewOrder(order));
}
});
socket.on('event', handlerFunc(dispatch));
// make sure the stores dispatch method is within scope
Explanation
Your event handler function were correctly broken down into a series of functions. However these functions were in the wrong order.
socket.on('new order', (order) => {
return (dispatch) => {
dispatch(socketNewOrder(order));
}
});
This is the correct order of the series functions that make up your eventHandler function:
socket.on('new order', (dispatch) => {
return (order) => {
dispatch(socketNewOrder(order));
}
});
Binding a handler function to a socket in the normal way would look like.
socket.on('event', handlerFunc)
So the handler function would only be called when the event is triggered.
This won't work for us if we need to pass dispatch to the handlerFunc when it is bound before handlerFunc is called when the event is triggered.
However we can solve this through the use of a functional programming technique called currying which allows us to break the event handler handler function into a series of functions that can be called at progressively later points in time.
Currying is when you break down a function that takes multiple
arguments into a series of functions that take part of the arguments.
There are two important points in time for socket events.
The handler function is bound to the socket instance
The handler function is called
We have access to the Redux store's dispatch method at timepoint one but not at timepoint two. Currying allows us to 'store' the dispatch method for timepoint two.
So what we can do is call a function with dispatch that returns our handlerFunction.
function handlerFunc(order){
dispatch(socketNewOrder(order));
}
function passDispatch(dispatch){
return handlerFunc
};
socket.on('event', passDispatch(dispatch));
So although this may look odd it results in exactly the same thing as the first example. Through currying although the event handler will be called at a later point in time we will still be able to dispatch actions as we have access to the dispatch variable.
We could use middleware to alleviate the repetition of currying our handler functions each time they are bound.