Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

updateInIndexedDB

Updates an existing record in an IndexedDB object store. If the record doesn't exist, it will be added.

TypeScript
Copied!
1/**
2 * Updates an existing record in an IndexedDB object store.
3 * If the record doesn't exist, it will be added.
4 *
5 * @param db - The open IDBDatabase instance.
6 * @param storeName - The name of the object store.
7 * @param value - The object to update (must include key if required by keyPath).
8 * @returns A Promise that resolves when the update is complete.
9 */
10export function updateInIndexedDB<T = any>(
11  db: IDBDatabase,
12  storeName: string,
13  value: T
14): Promise<void> {
15  return new Promise((resolve, reject) => {
16    const transaction = db.transaction([storeName], 'readwrite');
17    const store = transaction.objectStore(storeName);
18    const request = store.put(value);
19
20    request.onsuccess = () => resolve();
21    request.onerror = () => reject(request.error);
22  });
23}
  • Unified Insert/Update Logic

    Uses put, which handles both updates and inserts depending on key presence, simplifying CRUD logic.

  • Promise-Based Control Flow

    Enables clean integration with async/await, avoiding verbose event listener nesting.

  • Generic Typing Support

    Accepts any shape of data via <T>, allowing flexible type-safe updates across different stores.

  • Transactional Integrity

    Performs the operation within a readwrite transaction, ensuring atomicity and rollback on failure.

Tests | Examples

TypeScript
Copied!
1import { openIndexedDB } from './openIndexedDB';
2import { addToIndexedDB } from './addToIndexedDB';
3import { getFromIndexedDB } from './getFromIndexedDB';
4
5test('updateInIndexedDB - updates existing record', async () => {
6  const db = await openIndexedDB('TestDB_Update', 1, {
7    upgrade(db) {
8      if (!db.objectStoreNames.contains('users')) {
9        db.createObjectStore('users', { keyPath: 'id' });
10      }
11    }
12  });
13
14  await addToIndexedDB(db, 'users', { id: 1, name: 'Alice' });
15
16  await updateInIndexedDB(db, 'users', { id: 1, name: 'Alice Updated' });
17
18  const updated = await getFromIndexedDB(db, 'users', 1);
19  expect(updated).toEqual({ id: 1, name: 'Alice Updated' });
20
21  db.close();
22});
23
24test('updateInIndexedDB - inserts new record if not existing', async () => {
25  const db = await openIndexedDB('TestDB_UpdateInsert', 1, {
26    upgrade(db) {
27      db.createObjectStore('products', { keyPath: 'sku' });
28    }
29  });
30
31  await updateInIndexedDB(db, 'products', { sku: '123', title: 'Widget' });
32
33  const record = await getFromIndexedDB(db, 'products', '123');
34  expect(record).toEqual({ sku: '123', title: 'Widget' });
35
36  db.close();
37});

Common Use Cases

  • Editing Existing Records

    Modify fields on an object (e.g. updating a user profile, a task’s status, etc.).

  • Upserting Data from API Responses

    Store new or updated records after syncing with a remote source.

  • State Persistence

    Save application state (e.g. form drafts, session data) for later reuse or recovery.

  • Bulk Update Operations

    Iteratively apply updates to multiple records in a loop using this helper.

  • Versioned Local Caching

    Replace older cached entries with newer versions using consistent logic.

Codebase: Utilities -> Storage -> updateInIndexedDB | Yevhen Klymentiev