Skip to content

Instantly share code, notes, and snippets.

@balthazar
Created December 11, 2016 00:59
Show Gist options
  • Save balthazar/2a74a9fa2140eda087ed32ec69562ef9 to your computer and use it in GitHub Desktop.
Save balthazar/2a74a9fa2140eda087ed32ec69562ef9 to your computer and use it in GitHub Desktop.
import axios from 'axios'
import { noop, get } from 'lodash'
import { startLoader, stopLoader } from 'actions/loaders'
export default store => next => action => {
if (!action.type.startsWith('API:')) {
return next(action)
}
const { dispatch, getState } = store
const state = getState()
const prefix = action.type.split(':')[1]
const {
url,
method = 'get',
data,
query,
headers,
loaderName = prefix,
loaderData = true,
shouldFetch,
granuleError,
onSuccess = noop,
onError = noop,
onSuccessAfterDispatch = noop,
onErrorAfterDispatch = noop,
extra,
requireTokens,
} = action.payload
if (shouldFetch && !shouldFetch(state)) { return }
if (requireTokens && !state.auth) { return }
const r = {
url: `${CONFIG.api}${url}`,
method,
headers: {
Accept: 'application/json',
...headers,
},
}
if (data) {
r.data = data
}
if (query) {
r.params = query
}
if (state.auth) {
Object.assign(r.headers, state.auth.toJS())
}
dispatch(startLoader(loaderName, loaderData))
return axios.request(r)
.then(({ data, headers }) => {
let response = (data && (data.data || data.results)) || data
if (extra) {
response = {
response,
extra,
}
}
try {
dispatch({ type: 'TOKENS:PRE', payload: headers })
onSuccess(response, dispatch)
dispatch({ type: `${prefix}_SUCCESS`, payload: response })
onSuccessAfterDispatch(response, dispatch)
} catch (e) {
console.error(`>>>>>>> CODE ERR`, e.stack) // eslint-disable-line
}
return { success: response }
})
.catch(err => {
if (err.response.status === 403) { dispatch({ type: 'VALIDATE_TOKEN_ERROR' }) }
const response = get(err, 'response.data.errors') || get(err, 'response.data')
onError(response, dispatch)
dispatch({ type: `${prefix}_ERROR`, payload: response })
onErrorAfterDispatch(response, dispatch)
return { error: response }
})
.then(result => {
dispatch(stopLoader(loaderName))
if (granuleError) {
const granuleRes = granuleError(result.error, result.success)
if (granuleRes) { throw granuleRes }
}
// ensure the promise throw
if (result.error) {
throw result.error
}
return result.success
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment