Created
February 2, 2018 20:47
-
-
Save khovansky-al/54e69a7c92211c24e3c9750e03ddca28 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Ported from https://github.com/zslucky/redux-fetch-middleware | |
and fixed (though some things are still broken) by @khovansky | |
*/ | |
import { merge } from 'lodash' | |
import uuid from 'uuid' | |
import defaultConfig from './config' | |
// Default response type for module | |
const defaultRType = 'json' | |
function checkResponseType(type) { | |
const validType = String(type).toLowerCase() | |
const types = { | |
json: true, | |
text: true, | |
formData: true, | |
blob: true, | |
arrayBuffer: true, | |
} | |
return types[validType] ? validType : defaultRType | |
} | |
function restMiddlewareCreator(customConfig) { | |
const finalConfig = merge(defaultConfig, customConfig) | |
const { suffix, fetchOptions, responseType: configRType, debug } = finalConfig | |
return ({ dispatch, getState }) => next => (action) => { | |
if (!action || !action.$payload) { | |
return next(action) | |
} | |
const [REQUEST, SUCCESS, FAILURE] = suffix | |
const { type, $payload, meta } = action | |
const { url, options, onResponse, preFetchOptions, interceptors } = $payload | |
let opts = merge({}, fetchOptions, options) | |
// Edit fetch options in preFetchOptions method | |
if (preFetchOptions instanceof Function) { | |
opts = preFetchOptions(getState, opts) | |
} | |
// Check and get response type | |
const finalRType = checkResponseType($payload.responseType || configRType) | |
// Generate UID request if meta.$uid is empty | |
const uid = meta && meta.$uid ? meta.$uid : uuid.v4() | |
const preMeta = merge( | |
{}, | |
{ $uid: uid }, | |
(debug ? { $requestOptions: opts } : {}), | |
meta, | |
) | |
let resultMeta = null | |
// Request start | |
dispatch({ type: `${type}_${REQUEST}`, meta: preMeta }) | |
// Catch the response from service | |
return fetch(url, opts) | |
.then((response) => { | |
resultMeta = merge({}, { $response: response }, preMeta) | |
const responseJSON = response[finalRType]() | |
if ( | |
onResponse | |
&& (onResponse instanceof Function) | |
&& onResponse(response, preMeta, type) === false | |
) { | |
throw responseJSON | |
} | |
return responseJSON | |
}) | |
.then((data) => { | |
// Request success, dispatch the response data | |
dispatch({ type: `${type}_${SUCCESS}`, data, meta: resultMeta }) | |
if ( | |
interceptors && | |
interceptors.success && | |
interceptors.success instanceof Function | |
) interceptors.success({ dispatch, getState, data }) | |
}) | |
.catch((err) => { | |
// Request failure, dispatch the error | |
dispatch({ type: `${type}_${FAILURE}`, err, meta: resultMeta }) | |
if ( | |
interceptors && | |
interceptors.failure && | |
interceptors.failure instanceof Function | |
) interceptors.failure({ dispatch, getState, err }) | |
}) | |
} | |
} | |
export default restMiddlewareCreator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment