UNPKG

redux-thunk-actions

Version:

redux-thunk-actions ===================

77 lines (70 loc) 2.44 kB
import { createAction } from 'redux-actions'; /** * Creates an async action creator * * @param {String} TYPE the type of the action * @param {Function} fn the function to be called async * @param {Boolean} suppressException optionally do not throw exceptions * @return {Funtion} the action creator */ export function createActionThunk (type, fn, suppressException) { const TYPE_STARTED = `${type}_STARTED`; const TYPE_SUCCEEDED = `${type}_SUCCEEDED`; const TYPE_FAILED = `${type}_FAILED`; const TYPE_ENDED = `${type}_ENDED`; const actionCreators = { [TYPE_STARTED] : createAction(TYPE_STARTED), [TYPE_SUCCEEDED] : createAction(TYPE_SUCCEEDED), [TYPE_FAILED] : createAction(TYPE_FAILED), [TYPE_ENDED] : createAction(TYPE_ENDED) }; const successActionWithMeta = createAction(TYPE_SUCCEEDED, ({payload}) => payload, ({meta}) => meta); const factory = (...args) => (dispatch, getState, extra) => { let result; let startedAt = (new Date()).getTime(); dispatch(actionCreators[TYPE_STARTED](args)); const succeeded = (data) => { const action = data && data.payload ? successActionWithMeta(data) : actionCreators[TYPE_SUCCEEDED](data); dispatch(action); let endedAt = (new Date()).getTime(); dispatch(actionCreators[TYPE_ENDED]({ elapsed: endedAt - startedAt })); return data; }; const failed = (err) => { let endedAt = (new Date()).getTime(); dispatch(actionCreators[TYPE_FAILED](err)); dispatch(actionCreators[TYPE_ENDED]({ elapsed: endedAt - startedAt })); if(!suppressException) { throw err; } } try { result = fn(...args, {getState, dispatch, extra}); } catch (error) { failed(error); } // in case of async (promise), use success and fail callbacks. if (isPromise(result)) { return result.then(succeeded, failed); } return succeeded(result); } factory.NAME = type; factory.START = actionCreators[TYPE_STARTED].toString(); factory.STARTED = factory.START; factory.SUCCEEDED = actionCreators[TYPE_SUCCEEDED].toString(); factory.FAILED = actionCreators[TYPE_FAILED].toString(); factory.ENDED = actionCreators[TYPE_ENDED].toString(); return factory; } //helpers function isPromise(p) { return p && p.then && p.catch; }