This is a simple example on how to save data to PouchDB and / or save or load data to CouchDB
See the html code at the bottom of this post

In this example I started with retrieving data from a CouchDB
Create a new document and view it

✅ Document retrieved successfully:
{
"value": "James Bond",
"lastModified": "2025-11-23T20:53:10.797Z",
"description": "This i James Bond - Agent 007",
"_id": "demo_007",
"_rev": "1-fb22f16b8dd6ea5821472092fa7f71eb"
}
Raw value (unescaped):
James Bond
Press button Sync2CouchDB – and you will find the document in coucdb.

Where is PouchDB stored?
Google Chrome / Microsoft Edge:
Inspect Database and Object Stores: Click on the PouchDB database you want to inspect. You can then view its object stores and the data within them.
Open DevTools: Right-click on the webpage and select “Inspect” or press Ctrl + Shift + I (Windows/Linux) / Cmd + Option + I (macOS).
Navigate to Application Tab: In the DevTools panel, select the “Application” tab.
Expand IndexedDB: In the left-hand sidebar under “Storage,” expand the “IndexedDB” section. You will see a list of databases, including those created by PouchDB.

Code: remember to change your couchdb settings the the file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PouchDB Interactive Demo</title>
<style>
body { font-family: sans-serif; line-height: 1.6; padding: 20px; max-width: 700px; margin: 0 auto; }
input[type="text"], textarea { width: 100%; padding: 8px; margin-bottom: 10px; box-sizing: border-box; font-family: monospace; }
button { padding: 10px 15px; margin-right: 10px; cursor: pointer; }
button:disabled { cursor: not-allowed; background-color: #ccc; }
#output { background-color: #f4f4f4; border: 1px solid #ddd; padding: 15px; white-space: pre-wrap; word-wrap: break-word; min-height: 50px; margin-top: 20px; }
.section { border: 1px solid #ccc; padding: 20px; margin-top: 20px; border-radius: 5px; }
h2 { margin-top: 0; }
small { color: #555; }
</style>
https://cdn.jsdelivr.net/npm/pouchdb@9.0.0/dist/pouchdb.min.js
https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js
</head>
</head>
<body>
<h1>Header 1 PouchDB Interactive Demo</h1>
<p>Store, retrieve, list, and query JSON objects from a local in-browser database using JSONata.</p>
<div class="section">
<h2>1. Store Data</h2>
<label for="docIdStore">Document ID (_id)</label>
<input type="text" id="docIdStore" placeholder="e.g., user_profile_001">
<label for="docValue">Data (will be stored as `value` property)</label>
<input type="text" id="docValue" placeholder="e.g., Charlie Day">
<label for="docDescription">Description (optional)</label>
<input type="text" id="docDescription" placeholder="e.g., This is a test document">
<button onclick="storeData()" disabled>Store/Update Document</button>
</div>
<div class="section">
<h2>2. Retrieve Data</h2>
<label for="docIdRetrieve">Document ID (_id) to retrieve</label>
<input type="text" id="docIdRetrieve" placeholder="Enter an ID to fetch">
<button onclick="retrieveData()" disabled>Retrieve Document</button>
</div>
<div class="section">
<h2>3. List Documents</h2>
<label for="filterId">Filter by ID (optional prefix)</label>
<input type="text" id="filterId" placeholder="e.g., user_">
<button onclick="listDocuments()" disabled>List Document IDs</button>
</div>
<div class="section">
<h2>4. Query with JSONata</h2>
<label for="jsonataQuery">JSONata Query</label>
<textarea id="jsonataQuery" rows="4" placeholder="e.g., **[value='Rum Ham 🥓']"></textarea>
<p><small>This query runs against an array of all documents in the database. Example: to find all docs where the 'value' property is 'test', use <code>**[value='test']</code></small></p>
<button onclick="queryWithJsonata()" disabled>Run Query</button>
</div>
<button id="syncButton" disabled>Synk2CouchDB</button>
<button id="replicateButton" disabled>Repliker fra CouchDB</button>
<h2>Output</h2>
<pre id="output">Loading libraries...</pre>
<script>
let db;
let outputDiv;
// Wait for the DOM and all scripts to be fully loaded.
window.addEventListener('load', () => {
outputDiv = document.getElementById('output');
const allButtons = document.querySelectorAll('button');
// Check if libraries loaded correctly
if (typeof PouchDB === 'undefined' || typeof jsonata === 'undefined') {
outputDiv.textContent = '❌ CRITICAL ERROR: A database library (PouchDB or JSONata) failed to load. Please check your network connection and browser console, then refresh the page.';
console.error("PouchDB or JSONata is not defined. Buttons will remain disabled.");
return; // Keep buttons disabled
}
// Initialize database
db = new PouchDB('user_data_db');
outputDiv.textContent = "Database and libraries loaded successfully. Ready.";
// Enable all buttons
allButtons.forEach(button => {
button.disabled = false;
});
document.getElementById('syncButton').disabled = false;
document.getElementById('replicateButton').disabled = false;
// --- REPLIKERING FRA COUCHDB ---
document.getElementById('replicateButton').addEventListener('click', async function() {
outputDiv.textContent = 'Starter replikering fra CouchDB...';
try {
const remoteDb = new PouchDB('http://admin:admin@localhost:5984/mypouchdb');
const result = await db.replicate.from(remoteDb);
outputDiv.textContent = '✅ Replikering fullført!\n\n' + JSON.stringify(result, null, 2);
} catch (err) {
outputDiv.textContent = '❌ Feil under replikering:\n\n' + err.toString();
}
});
// --- SYNKRONISERING ---
document.getElementById('syncButton').addEventListener('click', async function() {
outputDiv.textContent = 'Starter synkronisering til CouchDB...';
try {
// Bruk brukernavn og passord i URL
const remoteDb = new PouchDB('http://admin:admin@localhost:5984/mypouchdb');
const result = await db.replicate.to(remoteDb);
outputDiv.textContent = '✅ Synkronisering fullført!\n\n' + JSON.stringify(result, null, 2);
} catch (err) {
outputDiv.textContent = '❌ Feil under synkronisering:\n\n' + err.toString();
}
});
});
// --- STORING DATA ---
async function storeData() {
const docId = document.getElementById('docIdStore').value;
const docValue = document.getElementById('docValue').value;
const docDescription = document.getElementById('docDescription').value;
// Normalize input: handle cases where the user pasted a quoted JSON string
// or a string with escaped quotes (e.g. "*.{\"id\": _id}"). We'll try to
// unquote/unescape first, then if the result looks like a JSON object/array
// parse it so we store an actual object instead of a JSON string.
let valueToStore = docValue;
try {
// Unwrap up to 3 times if the value is a quoted JSON string
let attempts = 0;
while (typeof valueToStore === 'string' && /^\s*"[\s\S]*"\s*$/.test(valueToStore) && attempts < 3) {
try {
valueToStore = JSON.parse(valueToStore);
attempts++;
} catch (e) {
break;
}
}
// Replace common escaped-quote sequences if present (heuristic)
if (typeof valueToStore === 'string' && /\\"/.test(valueToStore)) {
valueToStore = valueToStore.replace(/\\"/g, '"');
}
// If the (possibly unquoted/unescaped) value now looks like JSON object/array,
// parse it to store as a real object/array instead of a string.
if (typeof valueToStore === 'string' && /^\s*[\{\[]/.test(valueToStore)) {
try {
valueToStore = JSON.parse(valueToStore);
} catch (e) {
// leave as string
}
}
} catch (err) {
valueToStore = docValue;
}
console.log('Storing document value. original:', docValue, 'stored as:', valueToStore);
if (!docId || !docValue) {
outputDiv.textContent = '❌ Error: Both Document ID and Data fields are required to store a document.';
return;
}
const doc = {
_id: docId,
value: valueToStore,
lastModified: new Date().toISOString(),
description: docDescription
};
outputDiv.textContent = `[STORE] Attempting to store document with _id: ${docId}...`;
try {
const existingDoc = await db.get(docId);
console.warn(`⚠️ Document with _id '${docId}' already exists. Updating it.`);
const updatedDoc = { ...doc, _rev: existingDoc._rev };
const response = await db.put(updatedDoc);
outputDiv.textContent = '✅ Document updated successfully:\n\n' + JSON.stringify(response, null, 2);
} catch (err) {
if (err.status === 404) {
try {
const response = await db.put(doc);
outputDiv.textContent = '✅ Document stored successfully:\n\n' + JSON.stringify(response, null, 2);
} catch (putErr) {
outputDiv.textContent = '❌ Error storing new document:\n\n' + putErr.toString();
}
} else {
outputDiv.textContent = '❌ Error checking for document:\n\n' + err.toString();
}
}
}
// --- RETRIEVING DATA ---
async function retrieveData() {
const docId = document.getElementById('docIdRetrieve').value;
if (!docId) {
outputDiv.textContent = '❌ Error: Document ID is required to retrieve a document.';
return;
}
outputDiv.textContent = `[RETRIEVE] Attempting to retrieve document with _id: ${docId}...`;
try {
const doc = await db.get(docId);
// Show both the full document JSON and the raw value (if it's a string)
let displayText = '✅ Document retrieved successfully:\n\n' + JSON.stringify(doc, null, 2);
if (typeof doc.value === 'string') {
displayText += '\n\nRaw value (unescaped):\n' + doc.value;
}
outputDiv.textContent = displayText;
} catch (err) {
if (err.status === 404) {
outputDiv.textContent = `❌ Document with _id '${docId}' not found.`;
} else {
outputDiv.textContent = '❌ Error retrieving document:\n\n' + err.toString();
}
}
}
// --- LISTING DOCUMENTS ---
async function listDocuments() {
const filterValue = document.getElementById('filterId').value;
outputDiv.textContent = 'Fetching document list...';
const options = { include_docs: false };
if (filterValue) {
options.startkey = filterValue;
options.endkey = filterValue + '\ufff0';
}
try {
const result = await db.allDocs(options);
let docListText = 'No documents found matching the filter.';
if (result.rows.length > 0) {
const ids = result.rows.map(row => row.id);
docListText = `Found ${result.rows.length} document(s):\n\n- ${ids.join('\n- ')}`;
}
outputDiv.textContent = docListText;
} catch (err) {
outputDiv.textContent = '❌ Error listing documents:\n\n' + err.toString();
}
}
// --- QUERYING WITH JSONATA ---
async function queryWithJsonata() {
const jsonataQueryString = document.getElementById('jsonataQuery').value;
if (!jsonataQueryString) {
outputDiv.textContent = '❌ Error: JSONata Query cannot be empty.';
return;
}
if (typeof jsonata === 'undefined') {
outputDiv.textContent = '❌ Error: JSONata library not loaded. Check the script tag.';
return;
}
outputDiv.textContent = 'Fetching all documents and running JSONata query...';
try {
const allDocsResult = await db.allDocs({ include_docs: true });
const docs = allDocsResult.rows.map(row => row.doc);
if (docs.length === 0) {
outputDiv.textContent = 'Database is empty. Nothing to query.';
return;
}
const expression = jsonata(jsonataQueryString);
const result = await expression.evaluate(docs);
outputDiv.textContent = '✅ JSONata query executed successfully:\n\n' + JSON.stringify(result, null, 2);
} catch (err) {
outputDiv.textContent = '❌ Error executing JSONata query:\n\n' + err.toString();
}
}
</script>
</body>
</html>
Leave a comment