Skip to content

JavaScript IndexedDB

IndexedDB is a powerful, client-side storage API that is more robust than other local storage solutions available in web browsers. It allows for significant amounts of structured data to be stored and manipulated asynchronously by web applications. IndexedDB is perfect for applications that require offline data storage, high performance, and rich query capabilities without reliance on a network connection.

Setting Up an IndexedDB Database

Step 1: Open a Database

To use IndexedDB, the first step is to open a database. Here is how you can create or open an IndexedDB database. After a successful operation, we close the database to prevent unwanted side effects in other examples. You may skip this step in your own code, or include it if needed.

Warning: Calling deleteDatabase() will wipe all data for this database. This is only for testing purposes and should not be used in production.


Output appears here after Run.

Step 2: Creating Object Stores

Once the database is opened, you can proceed to create an object store which is akin to a table in relational databases. Note that this can only be done during a version upgrade (when opening the database with a higher version number). The event to listen for is onupgradeneeded.


Output appears here after Run.

Transactions

Once your database and object stores are set up, you'll need to manage data operations using transactions. A transaction in IndexedDB is a mechanism that groups multiple operations into a single unit of work that either completely succeeds or completely fails. It is essential for ensuring data consistency and integrity, especially when multiple operations depend on each other to produce a correct outcome.

How to Use Transactions in IndexedDB

Step 1: Starting a Transaction

To perform any operation in IndexedDB, you start by creating a transaction on a database. A transaction is created by specifying which object stores the transaction will involve and the mode of the transaction, which can be either "readonly" or "readwrite".

Step 2: Accessing an Object Store

Within a transaction, you can access one or more object stores to perform data operations.

Step 3: Performing Operations

Once you have access to an object store, you can execute various operations like adding, retrieving, updating, or deleting data. Each operation returns a request object that you can use to handle success or error events.

Step 4: Completing the Transaction

A transaction will automatically complete once all the operations issued in it have been resolved, either by succeeding or failing. You can also listen for the complete event on the transaction to perform actions after all operations have successfully finished.

Here is an example of a complete transaction:


Output appears here after Run.

Reading Data

To retrieve data, use store.get(key) or a cursor for iterating over multiple records. Here are quick examples:

Retrieving a single record:


Output appears here after Run.

Iterating with a cursor:


Output appears here after Run.

Updating and Deleting Records

To modify existing data, use store.put() with the same key. To remove data, use store.delete(key).

Updating a record:


Output appears here after Run.

Deleting a record:


Output appears here after Run.

How to view IndexedDB content in your browser

After storing and manipulating data, you may want to inspect what's actually saved in your browser. Most modern browsers show you what is stored in the IndexedDB. Below is the example from Chrome's developer tools:

IndexedDB

Best Practices for Using Transactions

To ensure your IndexedDB implementation remains reliable and performant, follow these guidelines:

  1. Minimize the Scope: Keep transactions as small as possible, both in terms of the number of operations and the duration. This reduces the likelihood of conflicts and improves performance.
  2. Error Handling: Always implement error handling on both the request and transaction levels. This helps in diagnosing issues and preventing partial updates that could lead to data corruption.
  3. Concurrency: Understand that while IndexedDB is asynchronous and non-blocking, transactions on the same database are queued and executed serially to prevent data races and inconsistencies.

Conclusion

IndexedDB provides a robust platform for complex data management in web applications, making it an essential tool for modern web developers. Through the proper implementation of its features, developers can efficiently store, retrieve, update, and delete client-side data, enhancing application performance and user experience.

Practice

What are the characteristics of the IndexedDB in JavaScript?

Dual-run preview — compare with live Symfony routes.