useAllDocs
Overview
useAllDocs
is the hook version of db.allDocs()
. It gives you the
ability to fetch multiple documents by their ids.
It doesn't need the creation of a secondary index. This means that it is useable right away, even when not all documents did sync.
As all hooks, it subscribes to updates.
useAllDocs
can only be invoked from a component nested inside of a <Provider />
.
Parameters
useAllDocs
expects a single options object. It has the same options as
db.allDocs()
. Options descriptions are copied from the PouchDB API
page.
options: object
-db.allDocs()
option object.options.include_docs?: boolean
- Include the document itself in each row in thedoc
field. Otherwise by default you can only get the_id
and_rev
properties.options.conflicts?: boolean
- Include conflict information in the_conflicts
field of a doc.options.attachments?: boolean
- Include attachment data as base64-encoded string.options.binary?: boolean
- Return attachment data as Blobs, instead of as base64-encoded strings.options.startkey?: string
- Get documents with IDs in a certain range. The range starts with this key.options.endkey?: string
- Get documents with IDs in a certain range. The range ends with this key.options.inclusive_end?: boolean
- Include documents having an ID equal to the givenoptions.endkey
. Default istrue
.options.limit?: number
- Maximum number of documents to return.options.skip?: number
- Number of documents to skip before returning (warning: poor performance!).options.descending?: boolean
- Reverse the order of the output documents. Note that the order ofoptions.startkey
andoptions.endkey
is reversed whendescending
istrue
.options.key?: string
- Only return documents with IDs matching this string key.options.keys?: string[]
- Fetch multiple known IDs in a single shot.- Neither
options.startkey
noroptions.endkey
can be specified with this option. - The rows are returned in the same order as in the supplied
keys
array. - The row for a deleted document will have the revision ID of the deletion, and an extra key
deleted: true
in thevalue
property. - The row for a nonexistent document will only contain an
error
property with the value"not_found"
. - For more details, see the
db.allDocs() documentation
or the CouchDB query options documentation.
- Neither
options.update_seq?: boolean
- Include anupdate_seq
value indicating which sequence id of the underlying database the view reflects.options.db?: string
- Selects the database to be used. The database is selected by it's name/key. The special key"_default"
selects the default database. Defaults to"_default"
.
keys
is check for equality with a deep equal algorithm. And only if it differentiate by value will it cause a new query be made.
Result
useAllDocs
results an object with those fields:
rows: object[]
- Array of objects that contain the requested information. Empty during the first fetch or during an error. Each object has following fields:id: string
-_id
of the document.key: string
-_id
of the document.value: object
- Object with one field:value.rev: string
-_rev
of the document.
doc?: PouchDB.Core.Document
- Ifoptions.include_docs
wastrue
, this field will contain the document. And ifattachments
is alsotrue
, the document will contain the attachment data in the"_attachments"
field.
offset: number
- Theskip
provided.total_rows: number
- The total number of non-deleted documents in the database.update_seq?: number | string
- Ifupdate_seq
istrue
, this will contain the sequence id of the underlying database.state: 'loading' | 'done' | 'error'
- Current state of the hook.loading
- It is loading the documents. Or it is loading the updated version of them.done
- The documents are loaded, and no update is being loaded.error
- There was an error with fetching the documents. Look into theerror
field.
loading: boolean
- It is loading. The state isloading
. This is only a shorthand.error: PouchDB.Error | null
- If there was an error, then this field will contain the error. The error is reset tonull
once a fetch was successful.
Example Usage
useAllDocs
is useful for many operations where you need to load multiple documents.
Prefix search
If you sort your documents by _id
, then you can use useAllDocs
to load all documents with a prefix. Read more
at the 12 pro tips section 7.
The '\ufff0'
is a special high Unicode character, that is sorted after most others.
If a document, that fall into this range, gets added, updated or deleted, then the rows
will be updated
accordingly.
import React from 'react'
import { useAllDocs } from 'use-pouchdb'
import { ErrorMessage } from './ErrorMessage'
export function Comments({ id }) {
const commentsPrefix = `comments_${id}`
const { rows, loading, state, error } = useAllDocs({
startkey: commentsPrefix,
endkey: commentsPrefix + '\ufff0',
include_docs: true,
})
if (state === 'error') {
return <ErrorMessage error={error} />
}
if (loading && rows.length === 0) {
return null
}
return (
<div>
<h4>Comments</h4>
<div>
{rows.map(row => (
<section key={row.id}>
<h5>{row.doc.username} commented</h5>
{!row.value.rev.startsWith('1-') && <span>Edited</span>}
<p>{row.doc.comment}</p>
</section>
))}
</div>
</div>
)
}
Load multiple documents by id
useAllDocs
can also load multiple documents by their IDs.
import React from 'react'
import { useAllDocs } from 'use-pouchdb'
import { ErrorMessage } from './ErrorMessage'
export function Related({ doc }) {
const { rows, loading, state, error } = useAllDocs({
keys: doc.related || [], // doc.related is an Array of IDs.
include_docs: true,
})
if (state === 'error') {
return <ErrorMessage error={error} />
}
if (loading && rows.length === 0) {
return null
}
return (
<div>
<h4>Read more</h4>
<ul>
{rows.map(row => (
<li key={row.id}>{row.doc.title}</li>
))}
</ul>
</div>
)
}
Descending
It is imported to remember that options.startkey
and options.endkey
switch, when options.descending
is true
.
import React from 'react'
import { useAllDocs } from 'use-pouchdb'
import ms from 'milliseconds'
import { ErrorMessage } from './ErrorMessage'
export function LastBookings() {
const midnight = new Date()
midnight.setHours(0)
midnight.setMinutes(0)
midnight.setSeconds(0)
// this goes from midnight to 7 days ago.
const { rows, loading, state, error } = useAllDocs({
// start midnight
startkey: 'bookings_' + midnight.toJSON(),
// End at endkey
// the date 7 days ago is the end.
endkey: 'bookings_' + new Date(midnight.getTime() - ms.days(7)).toJSON(),
include_docs: true,
descending: true,
})
if (state === 'error') {
return <ErrorMessage error={error} />
}
if (loading && rows.length === 0) {
return null
}
return (
<div>
<h4>Bookings</h4>
<ul>
{rows.map(row => (
<li key={row.id}>
{row.doc.amount}€ from {row.doc.partner}
</li>
))}
</ul>
</div>
)
}
Select a database
import React from 'react'
import { useAllDocs } from 'use-pouchdb'
import { ErrorMessage } from './ErrorMessage'
export function Comments({ id, isLocalReady }) {
const commentsPrefix = `comments_${id}`
const { rows, loading, state, error } = useAllDocs({
startkey: commentsPrefix,
endkey: commentsPrefix + '\ufff0',
include_docs: true,
// Select the database used
db: isLocalReady ? 'local' : 'remote',
})
if (state === 'error') {
return <ErrorMessage error={error} />
}
if (loading && rows.length === 0) {
return null
}
return (
<div>
<h4>Comments</h4>
<div>
{rows.map(row => (
<section key={row.id}>
<h5>{row.doc.username} commented</h5>
{!row.value.rev.startsWith('1-') && <span>Edited</span>}
<p>{row.doc.comment}</p>
</section>
))}
</div>
</div>
)
}