PouchDB.find is not a function

PouchDB.find is not a function

Debugging the Mango query Find for PouchDB Database for finding new documents.

ยท

4 min read

I am using CouchDB & PouchDB for one of my projects.

Now CouchDB is an amazing database that is

  • specifically designed for offline-first applications.
  • Has great replication support. So is insanely scalable.
  • Gives user management out of the box.
  • Individual database for each user.
  • Manage roles & give access based to databases based on roles.
  • Allow custom query-design documents, which pre-indexes the database & which leads to fast read/write times.

Due to the above reasons for basic CRUD-type apps, you don't even need a backend(with insane security), which is great for both development time & cost optimization.

There are many more benefits to CouchDB, these are just at top of my mind. There are a few trade-offs too, so be mindful of those & see if this suits your needs. One of the major drawbacks is the community support lacking. Most of the articles are out-of-date & most of the links are stale, this is often frustrating when you need an answer. It took me about 4 months to find the slack channel where the community lives. I believe it will be a smooth sail from here. ๐Ÿคž

While CouchDB sits on the server, PouchDB is the database that sits on the client-side. The app is supposed to talk to PouchDB & PouchDB then syncs with CouchDB behind the covers, so the app is not dependent on the server to be available. This neat structure is what allows CouchDB to be an awesome Offline First database. Do note, using PouchDB is not mandatory though.

####Note: If you plan to use this or any other similar offline first mechanisms for your app understand the trade-offs of offline first structure (whether, CouchDB or not). Some risks that you will have to plan for

  • Possibility of data loss when offline.
  • Data conflicts between the offline & online version.

There are more, do your research before so that you are not surprised later & see if you can incorporate contingency plans for any issues. CouchDB has a really good conflict management structure though.

Now one of the most basics of using any database is querying. Other than the get method, CouchDB & PouchDB use Mango queries. Which is very similar to MongoDB queries(the wordplay!!!).

The most common query is PouchDB.find which is actually written like

var res = await this.pouchDB.find(
                              {selector: 
                                    selector
                               }
                 )

Now when I incorporated this in my solution, it kept throwing the error PouchDB.find is not a function. Here is more detail on this...

Issue

Cant using the mango query find. Getting error PouchDB.find is not a function

Info

  • Environment: Browser - Reactjs
  • Platform: Chrome
  • Adapter: IndexedDB
  • Server: CouchDB

Reproduce

Now as per the docs here we need to use the plugin pouchdb-find to be able to use Mango queries.

image.png

But as mentioned here that pouchdb-find is now merged with PouchDB, so should not be needed at all.

image.png

So I tried using pouchdb-find plugin with both pouchdb & pouchdb-browser. It just didn't work.

####Options tried:

Option1

import PouchDB from 'pouchdb';
import pouchAuth from 'pouchdb-authentication';
PouchDB.plugin(pouchAuth);
PouchDB.plugin(require('pouchdb-find').default);

Option2

import PouchDB from 'pouchdb';
import pouchAuth from 'pouchdb-authentication';
import pouchFind from 'pouchdb-find';
PouchDB.plugin(pouchAuth);
PouchDB.plugin(pouchFind);

Option3

import PouchDB from 'pouchdb-browser';
import pouchAuth from 'pouchdb-authentication';
import pouchFind from 'pouchdb-find';
PouchDB.plugin(pouchAuth);
PouchDB.plugin(pouchFind);

Option4

import PouchDB from 'pouchdb';
import pouchAuth from 'pouchdb-authentication';
PouchDB.plugin(pouchAuth);

####Notes:

  1. pouchdb-authentication is need to provide authentication if you are using CouchDBs inbuilt user management.

Well, the glitch wasn't in the plugin at all. It was about how the database was being called. So here is what I was doing

import PouchDB from 'pouchdb-browser';
import pouchAuth from 'pouchdb-authentication';
import pouchFind from 'pouchdb-find';
PouchDB.plugin(pouchAuth);
PouchDB.plugin(pouchFind);

...

const getDB = (dbName) => {

        const localDB = new PouchDB(dbName, {auto_compaction: true});

        return localDB;
}

const findDoc = async (input)=> {

         let db = await getDB(dbName).find({
                         selector: {
                            type: { $eq: props[2]}
                        },
                        limit: 1
                      })
}

What worked for me was

... same as above
const findDoc = async (input)=> {

         let db = await getDB(dbName)
              db = await db.find({
                         selector: {
                            type: { $eq: props[2]}
                         },
                         limit: 1
                      })
}

Thankfully the community helped me figure this out. You can read about detail on the issue here at github .

I don't know what is wrong in the first option. If you know, please do let me know.

Caio till the next time. Krishna.

ย