Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save franklinjavier/622099421e38b4699896e40a38b18678 to your computer and use it in GitHub Desktop.
Save franklinjavier/622099421e38b4699896e40a38b18678 to your computer and use it in GitHub Desktop.
Redux + fetch interceptors
/*
* WARNING: Mutates the fetchContext argument (by default the window or global context).
*
* A crude way to intercept fetch responses, and dispatch actions as needed. Using this
* for more global app concerns, where I may want to dispatch actions depending on the response
* status or body. e.g. When seeing a 401, dispatch a logout action.
*
* In most cases, I'd recommend using a middlware as shown in redux's real-world example.
* (https://github.com/reactjs/redux/blob/master/examples/real-world/middleware/api.js)
*
* Example:
*
* import { applyMiddleware, compose, createStore } from 'redux';
*
* // ...
*
* const enhancer = compose(
* httpInterceptor({
* 200: (dispatch, response) => console.log('Got ', response),
* 429: (dispatch, response) => dispatch({ type: 'TOO_MANY_REQUESTS', { payload: response } }),
* 500: (dispatch, response) => dispatch({ type: 'SERVER_ERROR', { payload: response } })
* }),
* applyMiddleware(...middlewares)
* );
*
* const store = createStore(rootReducer, initialState, enhancer);
*
*
* If you have full control over service modules, it's probably better
* to use AOP and wrap the service module instead of mutating the context. :)
*/
const httpInterceptor = (statusHandlers = {}, fetchContext = global) => {
const _fetch = fetchContext.fetch;
return (createStore) => (reducer, initialState, enhancer) => {
const store = createStore(reducer, initialState, enhancer);
fetchContext.fetch = async (url, options) => {
const resp = await _fetch(url, options);
const maybeHandler = statusHandlers[`${resp.status}`];
maybeHandler && maybeHandler(store.dispatch, resp);
return resp;
};
return store;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment