pouchdb-redux-helper v0.11.0
pouchdb-redux-helper
Helpers for working with PouchDB in React with Redux store.
pouchdb-redux-helper consists of:
createCRUDfunction for creating reducers, actionTypes, actions and route paths.helper functions for connecting components with store
pouchdb-redux-helpers uses and depends on:
immutablejs for storing data
redux-thunk for handling actions
poouchdb-redux-helper is currently considered experimental software.
Installation
$ npm install pouchdb-redux-helper --saveUsage
Create CRUD
createCRUD(db, mountPoint, [prefix=null], [opts={}])This function return reducer and redux helpers for given resource type in given database.
Options
db: PouchDB databasemountPoint: unique name of CRUD that defines where it will be mounted in state as well to give action types unique prefixprefix: prefix to use for document id for creating new object and in allDocs. Equal tomountPointif not specified.opts: optionsstartkey- startkey for this crud, defaultmountPoint-endkey- endkey for this crud, defaultmountPoint-\uffff
Returns
It returns object consisting of:
actionsactions.allDocs(folder='', params, opts)actions.query(fun, folder='', params, opts)actions.get(docId, params, opts)actions.put(doc, params, opts)actions.remove(doc, params, opts)Options for actions:
fun: query functionfolder: folder where to save document idsparams: params to delegate to pouchdb service methodopts: additional options to add to actiondoc: documentdocId: document id
actionTypesaction types for actions above (allDocs, query, get, put, remove)
reducerReducer for given CRUD. It is immutable.Map object with:
documents: currently loaded documents, a map of docId: doc structurefoldersis a map of document ids for given database query. It has folderName:doc1Id, doc2Id,... structure.
mountPointmountPoint from option
pathspaths for crud routes (list, detail, edit, create)
urlPrefixurlPrefix for using in routes
dbPouchDB database
Example Usage
import thunk from 'redux-thunk';
import { createCRUD } from 'pouchdb-redux-helper';
//...
const db = PouchDB('testdb');
// get CRUD
const projectsCrud = createCRUD(db, 'projects');
// reducers
const reducers = combineReducers({
[projectsCrud.mountPoint]: projectsCrud.reducer,
});
// create store
const finalCreateStore = compose(
applyMiddleware(...[thunk]),
)(createStore);
const store = finalCreateStore(reducers);
// allDocs actionExample of calling allDocs action of projectsCrud.
store.dispatch(projectsCrud.actions.allDocs('all'));When previous example is executed, following will happen:
thunk will dispatch
POUCHDB_projects_allDocs_requestaction and execute PouchDBallDocsas promise.If promise resolves
2.1. thunk will dispatch
POUCHDB_projects_allDocs_successaction with result2.2. store will merge received documents with existing state in
state.projects.documentsand update document ids instate.projects.folders.allList.If error occurs
POUCHDB_projects_allDocs_failureaction will be dispatched with error
Connect containers helper functions
connectList
Decorator connects wrapped Component with documents from the state as property.
Query options can be passed to PouchDB, such as query function, startkey, endkey,
etc. If state does not already contains folder with documents, they are loaded.
connectList(crud, opts={}, mapStateToProps, mapDispatchToProps)Options
crud: crud obtained fromcreateCRUDopts:opts.options: options to pass to PouchDB. Ifoptions.funis given,querywill be executed, otherwiseallDocswhich starts withmountPoint-opts.folder: folder where to save result. If empty this is serialized fromopts.optionspropName="items": name of property to pass to wrapped component
mapStateToProps: custom mapStateToProps to delegate toconnectmapDispatchToProps: mapDispatchToProps to delegate toconnect
Example usage
const ProjectList = ({isLoading, items}) => {(
if (isLoading) {
return <div>loading...</div>
}
return (<ul>
{ items.map(item => <li key={item.get('_id')}>item.get('name')</li>) }
</ul>)
)};
// connected component contains all documents
export const ProjectListContainer = containers.connectList(
projectsCrud, {folder: 'all'}
)(ProjectList);
// connected component contains only starred projects
// it assumes view named 'starredProjects' exists in design documents
export const StarredProjectListContainer = containers.connectList(
projectsCrud, {fun: 'starredProjects'}
)(ProjectList);connectSingleItem
Decorator connects wrapped Component with single document.
docId would be resolved from:
- component own property,
mapStateToPropsfunction if it returnsdetailOpt,optsargument
Example usage
export const ProjectDetail = ({isLoading, item, dispatch, onRemove}) => {
if (isLoading) {
return <div>loading...</div>
}
return (
<span>{ item.get('name') }</span>
)
}
// connected component with own property, ie:
// <ProjectDetailContainer docId="project-1" />
export const ProjectDetailContainer = containers.connectSingleItem(
projectsCrud, {}
)(ProjectDetail);
// connected component with docId from router
// <ProjectDetailContainer />
export const ProjectDetailContainerFromUrl = containers.connectSingleItem(
projectsCrud, {}, state => ({
singleItemOpts: {docId: state.router.params.id},
})
)(ProjectDetail);Options
crud: crud obtained fromcreateCRUDopts:propName="items": name of property to pass to wrapped component
Properties
docId: document id
Example usage
const ProjectDetail = ({items, dispatch}) => (
<div>{ item.get('name') }</div>
);
// displays project with docId from url id param
const ProjectDetailContainer = connect(state => ({ docId: state.router.params.id }))(
containers.connectSingleItem(projectsCrud)(ProjectDetail)
)Routes creating helper
Use crud.paths
const routes = (
<Route path="/" component={App}>
<Route path={projectsCrud.paths.list} component={AllProjectListContainer} />
</Route>
);Pagination
Decorator connects and paginate wrapped Component.
paginate(paginationOpts, crud, connectListOpts, mapStateToProps, mapDispatchToProps)Options
paginationOpts:paginationOpts.rowsPerPage: rows per pagepaginationOpts.startkey: startkey
Other options are equal to those in connectList.
Example app
TODO:
- upgrade babel to 6.x
Changelog
- 0.11.0 (unreleased)
- refactor
connectSingleItemto allow setting opts frommapStateToProps
- refactor
- 0.10.0
- refactor loading decorator to always render passed component with
isLoadingproperty instead of using customLoadingcomponent - loading component triggers load in componentWillReceiveProps
- loading component expect
actionas function andactionArgsas function arguments. - bugfixes
- refactor loading decorator to always render passed component with
- 0.9.0
- fixes in pagination
- 0.8.0
- save extra things received from query/allDocs in
folderVars. This includestotal_rows,offset,skip. - remove
queryFuncintroduced in 0.7.0 - pagination suport
- pass additional
optsinqueryandallDocsactions and save them in folder asfolderVars
- save extra things received from query/allDocs in
- 0.7.0
- add
queryFuncoption tocontainers.connectListoptions
- add
- 0.6.0
- use redux-thunk instead of custom middleware and service
- remove service, middleware modules
- remove
actionsin favor ofcreatePromiseAction
License
MIT