The Power of Offline Storage: Unlocking Seamless Web Experiences

Understanding IndexedDB

IndexedDB is an inbuilt database for browsers, providing a structured way to store data locally. It consists of databases, object stores, and transactions. A database is unique to each web application, and object stores are similar to tables in relational databases or collections in document databases. Transactions ensure data consistency and integrity.

// Create a new database
var request = indexedDB.open('MyDatabase');
request.onupgradeneeded = function(event) {
  var db = event.target.result;
  var objectStore = db.createObjectStore('myObjectStore', { keyPath: 'id' });
};

The Limitations of IndexedDB

While IndexedDB offers a robust solution for offline storage, it has its limitations. The low-level API can be cumbersome to work with, and structuring data or storing large amounts of data can be challenging. Additionally, IndexedDB only stores string data, making it susceptible to XSS attacks.

Enter Dexie.js: A Minimalistic Wrapper for IndexedDB

Dexie.js simplifies the process of creating databases, object stores, and storing data with IndexedDB. This lightweight wrapper provides a more intuitive API, making it easier to work with IndexedDB. With Dexie.js, developers can create databases, object stores, and store data with ease.

// Create a new database with Dexie.js
import Dexie from 'dexie';

const db = new Dexie('MyDatabase');
db.version(1).stores({
  myObjectStore: 'id, name, price'
});

Building a Market List App with Dexie.js and React

To demonstrate the power of IndexedDB and Dexie.js, let’s build a market list app with React. Our app will allow users to add items, delete items, and mark them as purchased. We’ll use Dexie.js to create a database, object stores, and store data offline.

Setting Up Our App

We’ll start by creating a new React app using a GitHub template. This will provide us with a basic structure and design for our app. We’ll then install the necessary dependencies, including Dexie.js and dexie-react-hooks.

// Install dependencies
npm install dexie dexie-react-hooks

Creating Our Database with Dexie

With Dexie.js, creating a database and object stores is straightforward. We’ll create a new database named MarketList and declare our object store, items. Our items object store will expect an object with properties name, price, and itemHasBeenPurchased, while the id will be provided by Dexie.

// Create a new database with Dexie.js
import Dexie from 'dexie';

const db = new Dexie('MarketList');
db.version(1).stores({
  items: '++id, name, price, itemHasBeenPurchased'
});

Using the Dexie React Hook

We’ll use the useLiveQuery hook from dexie-react-hooks to watch for changes in our IndexedDB database and re-render our React component when an update is made. This hook provides a simple way to query our database and retrieve data.

// Use the useLiveQuery hook
import { useLiveQuery } from 'dexie-react-hooks';
import { db } from './db';

function App() {
  const items = useLiveQuery(() => db.items.toArray());
  // Render items
}

Adding Items to Our Database

We’ll create a function named addItemToDb to add items to our database. This function will be called whenever we click on the ADD ITEM button. Our component will re-render each time the database is updated.

// Add item to database
function addItemToDb(item) {
  db.items.add(item);
}

Removing and Updating Items

We’ll also create functions to remove items from our database and mark them as purchased. These functions will use the db.[nameofobjectstore].remove and db.[nameofobjectstore].update methods to modify our database.

// Remove item from database
function removeItemFromDb(id) {
  db.items.delete(id);
}

// Update item in database
function updateItemInDb(id, updates) {
  db.items.update(id, updates);
}

Querying Our Database

With Dexie.js, we can use conditions to query our IndexedDB database. For example, we can get all items with a price above 10 USD by using a query method.

// Query database
function getItemsAbovePrice(price) {
  return db.items.where('price').above(price).toArray();
}

Leave a Reply