pouchdb-redux-helper
v0.11.0
Published
Helpers for working with PouchDB in React with Redux store.
Downloads
20
Maintainers
Readme
pouchdb-redux-helper
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.
Installation
$ npm install pouchdb-redux-helper --save
Usage
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 tomountPoint
if not specified.opts
: optionsstartkey
- startkey for this crud, defaultmountPoint-
endkey
- endkey for this crud, defaultmountPoint-\uffff
Returns
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
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 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
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 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
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,
mapStateToProps
function if it returnsdetailOpt
,opts
argument
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 fromcreateCRUD
opts
: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
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
License
MIT