Last active
September 20, 2016 08:19
-
-
Save crisu83/c81c364ae4f66f0bfc93e315a2d5c72b to your computer and use it in GitHub Desktop.
A work-in-progress implementation of an entity CRUD saga for redux-saga.
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
import isArray from 'lodash/isArray'; | |
import isFunction from 'lodash/isFunction'; | |
import isString from 'lodash/isString'; | |
import { takeLatest } from 'redux-saga'; | |
import { call, fork, put } from 'redux-saga/effects'; | |
import { arrayOf, Schema } from 'normalizr'; | |
import { callApi } from '../../api/helper'; | |
import { normalizeEntityResponse } from '../../common/helper'; | |
/** | |
* Creates an entity CRUD saga. | |
* | |
* @param {Schema} entitySchema | |
* @param {array} actionTypes | |
* @param {array} requestCreators | |
* @param {array} actionCreators | |
* @returns {Function} | |
*/ | |
const createEntityCrudSaga = ({ entitySchema, actionTypes, requestCreators, actionCreators }) => { | |
if (!entitySchema instanceof Schema) { | |
throw new Error('Argument "entitySchema" must be an instance of Schema.'); | |
} | |
if (!isArray(actionTypes) || actionTypes.length !== 4 || !actionTypes.map((type) => isString(type))) { | |
throw new Error('Argument "actionTypes" must be an array of four strings.'); | |
} | |
if (!isArray(requestCreators) || requestCreators.length !== 4 || !requestCreators.map((func) => isFunction(func))) { | |
throw new Error('Argument "requestCreators" must be an array of four functions.'); | |
} | |
if (!isArray(actionCreators) || actionCreators.length !== 3 || !actionCreators.map((func) => isFunction(func))) { | |
throw new Error('Argument "actionCreators" must be an array of three functions.'); | |
} | |
const [createActionType, updateActionType, readActionType, deleteActionType] = actionTypes; | |
const [createRequestCreator, updateRequestCreator, readRequestCreator, deleteRequestCreator] = requestCreators; | |
const [receiveActionCreator, removeActionCreator, errorActionCreator] = actionCreators; | |
function* createEntity({ payload: entity }) { | |
try { | |
const { bodyAsJson } = yield call(callApi, createRequestCreator(entity)); | |
const data = normalizeEntityResponse(bodyAsJson, entitySchema); | |
yield put(receiveActionCreator(data)); | |
} catch (error) { | |
console.error('Failed to create entity with error: "%s"', error); | |
} | |
} | |
function* updateEntity({ payload: entity }) { | |
try { | |
const { bodyAsJson } = yield call(callApi, updateRequestCreator(entity)); | |
const data = normalizeEntityResponse(bodyAsJson, entitySchema); | |
yield put(receiveActionCreator(data)); | |
} catch (error) { | |
console.error('Failed to update entity with error: "%s"', error); | |
} | |
} | |
function* readEntities({ payload: params }) { | |
try { | |
const { bodyAsJson } = yield call(callApi, readRequestCreator(params)); | |
const data = normalizeEntityResponse(bodyAsJson, arrayOf(entitySchema)); | |
yield put(receiveActionCreator(data)); | |
} catch (error) { | |
console.error('Failed to read entity with error: "%s"', error); | |
} | |
} | |
function* deleteEntity({ payload: id }) { | |
try { | |
const { response, bodyAsJson } = yield call(callApi, deleteRequestCreator(id)); | |
yield put(response.status === 200 | |
? removeActionCreator(id) | |
: errorActionCreator(bodyAsJson.message)); | |
} catch (error) { | |
console.error('Failed to delete entity with error: "%s"', error); | |
} | |
} | |
function* watchCreate() { | |
yield* takeLatest(createActionType, createEntity); | |
} | |
function* watchUpdate() { | |
yield* takeLatest(updateActionType, updateEntity); | |
} | |
function* watchRead() { | |
yield* takeLatest(readActionType, readEntities); | |
} | |
function* watchDelete() { | |
yield* takeLatest(deleteActionType, deleteEntity); | |
} | |
return function*() { | |
yield [ | |
fork(watchCreate), | |
fork(watchUpdate), | |
fork(watchRead), | |
fork(watchDelete) | |
]; | |
}; | |
}; | |
export default createEntityCrudSaga; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment