Skip to content

Instantly share code, notes, and snippets.

@viankakrisna
Created February 24, 2017 11:19
Show Gist options
  • Save viankakrisna/62e3138bd0d7b8b11d98f38516b51347 to your computer and use it in GitHub Desktop.
Save viankakrisna/62e3138bd0d7b8b11d98f38516b51347 to your computer and use it in GitHub Desktop.
import sanitizeQuery from 'helper/sanitizeQuery';
import serialize from 'helper/serialize';
const getSuccessActionType = KEY =>
type => [ KEY, type.toUpperCase(), 'SUCCESS' ].join('_');
const initialCollectionState = {
items: {},
list: {},
infiniteList: {},
pagination: {},
infinitePagination: {},
lastUpdated: 0,
};
const createCollectionReducer = (
key,
singleTypes = [ 'getone' ],
collectionTypes = [ 'getlist' ],
otherSingleTypes = [],
otherCollectionTypes = [],
id = 'ID',
additionalReducer = (state, action) => state,
) =>
(state = initialCollectionState, action) => {
const KEY = key.toUpperCase();
const SINGLE_KEYS = singleTypes
.map(getSuccessActionType(KEY))
.concat(otherSingleTypes);
const COLLECTION_KEYS = collectionTypes.map(getSuccessActionType(KEY));
if (SINGLE_KEYS.includes(action.type)) {
const payloadData = action.payload.data;
return {
...state,
lastUpdated: Date.now(),
items: { ...state.items, [payloadData[id]]: payloadData },
};
}
if (COLLECTION_KEYS.includes(action.type)) {
const getItemId = item => item[id];
const filterNewIds = (v, i, a) => a.indexOf(v) === i;
const payloadData = action.payload.data;
const infiniteQueryKey = serialize(
sanitizeQuery(action.payload.query, true),
);
const paginatedQueryKey = serialize(sanitizeQuery(action.payload.query));
const items = payloadData.items;
const pagination = payloadData.pagination;
const newIds = items.map(getItemId);
return {
...state,
lastUpdated: Date.now(),
items: {
...state.items,
...items.reduce((res, item) => {
res[item[id]] = item;
return res;
}, {}),
},
list: { ...state.list, [paginatedQueryKey]: newIds },
infiniteList: {
...state.infiniteList,
[infiniteQueryKey]: (state.infiniteList[infiniteQueryKey] || [])
.concat(newIds)
.filter(filterNewIds),
},
infinitePagination: {
...state.infiniteList,
[infiniteQueryKey]: pagination,
},
pagination: { ...state.pagination, [paginatedQueryKey]: pagination },
};
}
return additionalReducer(state, action);
};
export default createCollectionReducer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment