Helpers for working with PouchDB in React with Redux store.
pouchdb-redux-helper consists of:
-
createCRUD
function 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.
$ npm install pouchdb-redux-helper --save
createCRUD(db, mountPoint, [prefix=null], [opts={}])
This function return reducer and redux helpers for given resource type in given database.
-
db
: PouchDB database -
mountPoint
: unique name of CRUD that defines where it will be mounted in state as well to give action types unique prefix -
prefix
: prefix to use for document id for creating new object and in allDocs. Equal tomountPoint
if not specified. -
opts
: optionsstartkey
- startkey for this crud, defaultmountPoint-
endkey
- endkey for this crud, defaultmountPoint-\uffff
It returns object consisting of:
-
actions
actions.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
-
actionTypes
action types for actions above (allDocs, query, get, put, remove)
-
reducer
Reducer for given CRUD. It is immutable.Map object with:
documents
: currently loaded documents, a map of docId: doc structurefolders
is a map of document ids for given database query. It has folderName:[doc1Id, doc2Id,...] structure.
-
mountPoint
mountPoint from option
-
paths
paths for crud routes (list, detail, edit, create)
-
urlPrefix
urlPrefix for using in routes
-
db
PouchDB database
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 action
Example 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_request
action and execute PouchDBallDocs
as promise. -
If promise resolves
2.1. thunk will dispatch POUCHDB_projects_allDocs_success
action with result
2.2. store will merge received documents with existing state in
state.projects.documents
and update document ids in
state.projects.folders.all
List.
- If error occurs
POUCHDB_projects_allDocs_failure
action will be dispatched with error
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)
crud
: crud obtained fromcreateCRUD
opts
:opts.options
: options to pass to PouchDB. Ifoptions.fun
is given,query
will be executed, otherwiseallDocs
which starts withmountPoint-
opts.folder
: folder where to save result. If empty this is serialized fromopts.options
propName="items"
: name of property to pass to wrapped component
mapStateToProps
: custom mapStateToProps to delegate toconnect
mapDispatchToProps
: mapDispatchToProps to delegate toconnect
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);
Decorator connects wrapped Component with single document.
crud
: crud obtained fromcreateCRUD
opts
:propName="items"
: name of property to pass to wrapped component
docId
would be resolved from:
- component own property,
mapStateToProps
function if it returnsdetailOpt
,opts
argument
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);
Use crud.paths
const routes = (
<Route path="/" component={App}>
<Route path={projectsCrud.paths.list} component={AllProjectListContainer} />
</Route>
);
Decorator connects and paginate wrapped Component.
paginate(paginationOpts, crud, connectListOpts, mapStateToProps, mapDispatchToProps)
paginationOpts
:paginationOpts.rowsPerPage
: rows per pagepaginationOpts.startkey
: startkey
Other options are equal to those in connectList
.
- upgrade babel to 6.x
- 0.12.0 (unreleased)
- 0.11.0
- refactor
connectSingleItem
to allow setting opts frommapStateToProps
- refactor
- 0.10.0
- refactor loading decorator to always render passed component with
isLoading
property instead of using customLoading
component - loading component triggers load in componentWillReceiveProps
- loading component expect
action
as function andactionArgs
as 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
queryFunc
introduced in 0.7.0 - pagination suport
- pass additional
opts
inquery
andallDocs
actions and save them in folder asfolderVars
- save extra things received from query/allDocs in
- 0.7.0
- add
queryFunc
option tocontainers.connectList
options
- add
- 0.6.0
- use redux-thunk instead of custom middleware and service
- remove service, middleware modules
- remove
actions
in favor ofcreatePromiseAction
MIT