Skip to content

IndexedDB - Creating Data

All data operations in IndexedDB (Create, Read, Update, Delete - CRUD) must happen within a transaction. A transaction ensures data integrity by grouping a set of operations into a single atomic unit. If any operation within the transaction fails, the entire set is rolled back. This chapter focuses on creating and updating data.

To perform any data operation, you must follow these four steps:

  1. Get a database connection: Successfully open the database.
  2. Start a transaction: Call db.transaction() on the connection object.
  3. Get the object store: Request access to one or more object stores within that transaction.
  4. Perform the operation: Call methods like add(), put(), get(), or delete() on the object store instance.

Transactions are auto-committing. Once you have made all your requests and they have completed, and no more requests are pending, the transaction automatically commits and becomes inactive.

You create a transaction using the db.transaction() method:

const transaction = db.transaction(storeNames, mode);
  • storeNames: A string or an array of strings specifying the object stores you want to access.
  • mode: A string specifying the transaction type. The most common modes are:
    • readonly: For reading data. This is the default and allows multiple parallel transactions.
    • readwrite: For adding, updating, or deleting data. This locks the specified object stores, preventing other readwrite transactions on them.

Adding and Updating Data with add() and put()

Section titled “Adding and Updating Data with add() and put()”

Once you have an object store instance from your transaction, you can add or update data:

  • objectStore.add(data): Adds the data object to the store. If an object with the same primary key already exists, the operation will fail and the transaction’s onerror handler will be triggered with a ConstraintError.
  • objectStore.put(data): Adds the data object to the store. If an object with the same primary key already exists, it will be overwritten (updated). This method is often called ‘upsert’ (update or insert).

Both add() and put() are asynchronous and return an IDBRequest object. You can listen for success and error events on this request to know when the operation is complete.

This complete example sets up a simple form to add new notes to our ‘MyNotesAppDB’ database. It demonstrates the full transaction lifecycle for a write operation.

<!DOCTYPE html>
<html lang="en">
<head>
<title>Add Data to IndexedDB</title>
</head>
<body>
<h2>Add a New Note</h2>
<form id="add-note-form">
<input type="text" id="note-title" placeholder="Note Title" required>
<textarea id="note-content" placeholder="Content"></textarea>
<button type="submit">Add Note</button>
</form>
<div id="feedback"></div>
<script>
const dbName = "MyNotesAppDB";
const dbVersion = 1;
const feedbackDiv = document.getElementById('feedback');
let db;
const request = indexedDB.open(dbName, dbVersion);
request.onerror = (event) => console.error(`DB Error: ${event.target.error}`);
request.onsuccess = (event) => {
db = event.target.result;
console.log('Database connection ready.');
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('notes')) {
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
objectStore.createIndex("title", "title", { unique: false });
}
};
document.getElementById('add-note-form').addEventListener('submit', (event) => {
event.preventDefault();
if (!db) {
feedbackDiv.textContent = 'Database is not ready yet.';
return;
}
const title = document.getElementById('note-title').value;
const content = document.getElementById('note-content').value;
const newNote = {
title: title,
content: content,
created_at: new Date()
};
// 1. Create a transaction
const transaction = db.transaction(['notes'], 'readwrite');
// 2. Get the object store
const store = transaction.objectStore('notes');
// 3. Perform the operation
const addRequest = store.add(newNote);
addRequest.onsuccess = () => {
feedbackDiv.textContent = `Note '${title}' added successfully!`;
event.target.reset(); // Clear the form
};
addRequest.onerror = (event) => {
console.error(`Error adding note: ${event.target.error}`);
feedbackDiv.textContent = 'Error adding note.';
};
transaction.oncomplete = () => {
console.log('Transaction completed: database modification finished.');
};
transaction.onerror = (event) => {
console.error(`Transaction error: ${event.target.error}`);
};
});
</script>
</body>
</html>