Skip to content

Instantly share code, notes, and snippets.

@sdbondi
Created September 20, 2017 19:16
Show Gist options
  • Save sdbondi/891682398a12b6486ca7304868049103 to your computer and use it in GitHub Desktop.
Save sdbondi/891682398a12b6486ca7304868049103 to your computer and use it in GitHub Desktop.
import {put, call, select} from 'redux-saga/effects';
import {takeEvery} from 'redux-saga';
import feathers from '../feathers';
import createResourceActionCreators from '../actions/resource';
import {resource as resourceActions} from '../actions';
import resourceEndpoints from './endpoints';
const initialOptions = {
pagination: {perPage: 10, page: 1},
};
const getQueryPagination = p => ({
$skip: (p.page - 1) * p.perPage,
$limit: p.perPage,
});
const paginationSelector = resourceName => state =>
state[resourceName].resource.pagination;
export default function createResourceSagas(
resourceName,
options = initialOptions
) {
const actions = {
...resourceActions,
...createResourceActionCreators(resourceName),
};
const selectPagination = paginationSelector(resourceName);
const sagas = {
*fetch(service, {query, nextPage, cb}) {
try {
const pagination = options.disablePagination
? null
: yield select(selectPagination);
if (nextPage) {
// XXX: Mutation
pagination.page = nextPage;
}
const result = yield call(() =>
service.find({
query: options.disablePagination
? query
: {
...query,
...getQueryPagination({...options.pagination, ...pagination}),
},
})
);
if (cb && cb(null, result) === true) {
return;
}
yield put(actions.fetchReceive(result, nextPage));
} catch (error) {
if (cb && cb(error) === true) {
return;
}
yield put(actions.fetchError(error));
}
},
*create(service, {item, cb}) {
try {
const result = yield call(service.create.bind(service), item);
if (cb && cb(null, result) === true) {
return;
}
yield put(actions.createReceive(result));
} catch (error) {
if (cb && cb(error) === true) {
return;
}
yield put(actions.createError(error));
}
},
*update(service, {id, item, cb}) {
try {
const result = yield call(service.update.bind(service), id, item);
if (cb && cb(null, result) === true) {
return;
}
yield put(actions.updateReceive(result));
} catch (error) {
if (cb && cb(error) === true) {
return;
}
yield put(actions.updateError(error));
}
},
*patch(service, {id, item, cb}) {
try {
const result = yield call(service.patch.bind(service), id, item);
if (cb && cb(null, result) === true) {
return;
}
yield put(actions.updateReceive(result));
} catch (error) {
if (cb && cb(error) === true) {
return;
}
yield put(actions.updateError(error));
}
},
*remove(service, {id, cb}) {
try {
const result = yield call(service.remove.bind(service), id);
if (cb && cb(null, result) === true) {
return;
}
yield put(actions.removeReceive(result));
} catch (error) {
yield put(actions.removeError(error));
}
},
};
const namespaced = fn =>
function* nsFunction(service, action) {
if (action.ns !== resourceName) {
return;
}
yield* fn(service, action);
};
return function* root() {
const endpoint = resourceEndpoints[resourceName];
if (!endpoint) {
throw new Error(`Endpoint does not exist for resource ${resourceName}`);
}
const service = feathers.service(endpoint);
yield [
takeEvery(
actions.RESOURCE_FETCH_REQUEST,
namespaced(sagas.fetch),
service
),
takeEvery(
actions.RESOURCE_CREATE_REQUEST,
namespaced(sagas.create),
service
),
takeEvery(
actions.RESOURCE_UPDATE_REQUEST,
namespaced(sagas.update),
service
),
takeEvery(
actions.RESOURCE_PATCH_REQUEST,
namespaced(sagas.patch),
service
),
takeEvery(
actions.RESOURCE_REMOVE_REQUEST,
namespaced(sagas.remove),
service
),
];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment