IndexedDB is a powerful browser-based database that allows you to store and manipulate data on the client-side.
In this tutorial, we will explore how to create a basic CRUD (Create, Read, Update, Delete) using IndexedDB and the
idb
package in JavaScript. By the end of this tutorial, you'll be able to build simple web applications that can locally store, retrieve, update, and delete data.
Prerequisites
Before we begin, make sure you have a basic understanding of HTML, JavaScript, and web development concepts.
Setting Up the Project
- Create a new directory for your project and navigate to it in your terminal.
mkdir indexeddb-with-idb cd indexeddb-with-idb
- Create an HTML file (e.g.,
index.html
) and a JavaScript file (e.g.,app.js
) in your project directory.
touch index.html touch app.js
Creating the HTML Structure
In your
index.html
file, set up the basic HTML structure for your web application:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>IndexedDB CRUD App</title> <script src="https://cdn.jsdelivr.net/npm/idb@7.1.1/build/umd.min.js"></script> </head> <body> <h1>IndexedDB CRUD App</h1> <button id="readButton">Read Data</button> <form id="dataForm"> <span id="idInput"></span> <input type="text" id="nameInput" placeholder="Name" required> <input type="number" id="ageInput" placeholder="Age" required> <button type="submit" id="submitButton">Create Data</button> </form> <ul id="dataList"></ul> <script src="app.js"></script> </body> </html>
This HTML structure includes a button to read data, form for adding data, a list for displaying data, and references to the JavaScript file (
app.js
).You also load the
idb
package from CDN using script
tag inside the head
tag.Implementing the JavaScript Logic
In your
app.js
file, implement the JavaScript code for interacting with IndexedDB.You can copy paste this code:
const dbPromise = idb.openDB('my-database', 1, { upgrade(db) { if (!db.objectStoreNames.contains('data')) { const dataStore = db.createObjectStore('data', { keyPath: 'id', autoIncrement: true }); dataStore.createIndex('name', 'name', { unique: false }); dataStore.createIndex('age', 'age', { unique: false }); } }, }); const createData = async (name, age) => { const db = await dbPromise; const tx = db.transaction('data', 'readwrite'); const dataStore = tx.objectStore('data'); const id = await dataStore.add({ name, age }); await tx.done; return id; }; const readAllData = async () => { const db = await dbPromise; const tx = db.transaction('data', 'readonly'); const dataStore = tx.objectStore('data'); return dataStore.getAll(); }; const updateData = async (id, name, age) => { const db = await dbPromise; const tx = db.transaction('data', 'readwrite'); const dataStore = tx.objectStore('data'); await dataStore.put({ id, name, age }); await tx.done; }; const deleteData = async (id) => { const db = await dbPromise; const tx = db.transaction('data', 'readwrite'); const dataStore = tx.objectStore('data'); await dataStore.delete(id); await tx.done; }; const renderData = async () => { const dataList = document.getElementById('dataList'); dataList.innerHTML = ''; const data = await readAllData(); data.forEach((item) => { const listItem = document.createElement('li'); listItem.innerHTML = ` <strong>${item.name}</strong> (Age: ${item.age}) <button data-id="${item.id}" class="update-button">Update</button> <button data-id="${item.id}" class="delete-button">Delete</button> `; dataList.appendChild(listItem); }); const updateButtons = document.querySelectorAll('.update-button'); const deleteButtons = document.querySelectorAll('.delete-button'); updateButtons.forEach((button) => { button.addEventListener('click', async (e) => { const id = parseInt(e.target.getAttribute('data-id'), 10); const dataItem = data.find((item) => item.id === id); if (dataItem) { document.getElementById('idInput').value = dataItem.id; document.getElementById('nameInput').value = dataItem.name; document.getElementById('ageInput').value = dataItem.age; document.getElementById('submitButton').innerText = "Update Data"; } }); }); deleteButtons.forEach((button) => { button.addEventListener('click', async (e) => { const id = parseInt(e.target.getAttribute('data-id'), 10); await deleteData(id); await renderData(); }); }); }; const initApp = async () => { const dataForm = document.getElementById('dataForm'); dataForm.addEventListener('submit', async (e) => { e.preventDefault(); const idInput = document.getElementById('idInput'); const nameInput = document.getElementById('nameInput'); const ageInput = document.getElementById('ageInput'); const submitButton = document.getElementById('submitButton'); const id = idInput.value; const name = nameInput.value; const age = parseInt(ageInput.value, 10); if (name && !isNaN(age)) { if (id) { await updateData(id, name, age); } else { await createData(name, age); } idInput.value = ''; nameInput.value = ''; ageInput.value = ''; submitButton.innerText = "Add Data"; await renderData(); } }); const readButton = document.getElementById('readButton'); readButton.addEventListener('click', async (e) => { await renderData(); }); }; initApp();
In this JavaScript code:
- We import the
idb
package for working with IndexedDB using<script>
tag inindex.html
- We define functions for adding, retrieving, and deleting data.
- The
initApp
function initializes the application by adding event listeners and rendering existing data.
- The code creates an IndexedDB database named my-database with an object store data to store our data.
- The form allows users to add new data, and the list displays the existing data with delete buttons.
Running the Application
To run the application, open your
index.html
file in a web browser. You can now add, view, and delete data in your IndexedDB-powered CRUD web application.Congratulations! You've successfully built a basic CRUD web application using IndexedDB and the
idb
package in JavaScript. You can expand upon this foundation to create more complex applications with additional features and functionalities.