redux-easy-async
Version:
Redux Easy Async makes handling asynchronous actions, such as API requests, simple, reliable, and powerful
146 lines (128 loc) • 5.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createAsyncMiddleware = undefined;
var _get2 = require('lodash/get');
var _get3 = _interopRequireDefault(_get2);
var _uniqueId2 = require('lodash/uniqueId');
var _uniqueId3 = _interopRequireDefault(_uniqueId2);
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _constants = require('./lib/constants');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Creates an instance of middleware necessary to handle dispatched async actions created with
* {@link createAsyncAction}.
* @kind function
* @param {object} options options to create middleware with.
* @param {object} [options.requestOptions={}] options that will be passed to all action's
* `makeRequest` functions: e.g. `makeRequest(state, requestOptions)`.
* @param {string} [options.namespace=REDUX_EASY_ASYNC_NAMESPACE] the action type the
* middleware will listen for. You most likely don't want to modify this unless for some reason
* you want multiple instances of async middleware.
*
* @return {function} redux middleware for handling async actions
*
* @example
* import { createAsyncMiddleware } from 'redux-easy-async';
* const asyncMiddleware = createAsyncMiddleware();
*
* ...
*
* // Now add to your middlewares whereever your store is created.
* // Typically this looks something like:
* // const middlewares = [asyncMiddleware, ...other middlewares]
*/
var createAsyncMiddleware = exports.createAsyncMiddleware = function createAsyncMiddleware() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _options$namespace = options.namespace,
namespace = _options$namespace === undefined ? _constants.REDUX_EASY_ASYNC_NAMESPACE : _options$namespace,
requestOptions = options.requestOptions;
// Return Redux middleware
return function (_ref) {
var dispatch = _ref.dispatch,
getState = _ref.getState;
return function (next) {
return function (action) {
// Normal action: pass it on
if (action.type !== namespace) return next(action);
// configuration option defaults
var startActionCreator = action.startActionCreator,
successActionCreator = action.successActionCreator,
failActionCreator = action.failActionCreator,
actionName = action.actionName,
makeRequest = action.makeRequest,
_action$meta = action.meta,
meta = _action$meta === undefined ? {} : _action$meta,
_action$actionCreator = action.actionCreatorArgs,
actionCreatorArgs = _action$actionCreator === undefined ? {} : _action$actionCreator,
_action$shouldMakeReq = action.shouldMakeRequest,
shouldMakeRequest = _action$shouldMakeReq === undefined ? function () {
return true;
} : _action$shouldMakeReq,
_action$parseStart = action.parseStart,
parseStart = _action$parseStart === undefined ? function () {
return null;
} : _action$parseStart,
_action$parseSuccess = action.parseSuccess,
parseSuccess = _action$parseSuccess === undefined ? function (resp) {
return resp;
} : _action$parseSuccess,
_action$parseFail = action.parseFail,
parseFail = _action$parseFail === undefined ? function (resp) {
return resp;
} : _action$parseFail;
if (!shouldMakeRequest(getState())) return false;
// create a unique ID for each request
var asyncID = (0, _uniqueId3.default)('asyncID');
// make the request and save the returned promise
var req = makeRequest(getState(), requestOptions);
// save the time the request was made
var requestStartTime = Date.now();
if (typeof (0, _get3.default)(req, 'then') !== 'function') {
throw new Error('makeRequest() for action "' + actionName + '" must return a promise.');
}
dispatch(startActionCreator({
payload: parseStart(),
meta: _extends({}, meta, {
actionName: actionName,
actionCreatorArgs: actionCreatorArgs,
asyncType: 'start',
asyncID: asyncID,
requestStartTime: requestStartTime
})
}));
req.then(function (resp) {
return dispatch(successActionCreator({
payload: parseSuccess(resp),
// pass the response and actionName as part of the meta
meta: _extends({}, meta, {
actionName: actionName,
actionCreatorArgs: actionCreatorArgs,
asyncType: 'success',
asyncID: asyncID,
requestStartTime: requestStartTime,
resp: resp,
requestDuration: Date.now() - requestStartTime
})
}));
}, function (resp) {
return dispatch(failActionCreator({
payload: parseFail(resp),
// pass the response and actionName as part of the meta
meta: _extends({}, meta, {
actionName: actionName,
actionCreatorArgs: actionCreatorArgs,
asyncType: 'fail',
asyncID: asyncID,
requestStartTime: requestStartTime,
resp: resp,
requestDuration: Date.now() - requestStartTime
})
}));
});
return req;
};
};
};
};