DEV Community

Cover image for IndexedDb A bigger LocalStorage
Anas Mustafa
Anas Mustafa

Posted on

IndexedDb A bigger LocalStorage

what is indexed let's look at the MDN definition of indexedDB: IndexedDB is a low-level API for client-side storage of significant amounts of structured data, including files/blobs.
so essentially we can use it when the local storage is too small for your needs.

note: IndexedDB is a mix between SQL and NoSQL databases as its a Transactional db like SQL databases but it also a js object oriented db like NOSQL databases

table

  • creating the database
  • creating the store
  • creating transaction
  • doing crud operation


IDBFactory{
    open(name, version?: number): // opening a database returns IDBOpenDBRequest
    deleteDatabase(name: string): 
    cmp(first: any, second: any): 
    databases(): 
}
IDBOpenDBRequest{
    onblocked:
    onupgradeneeded:
    addEventListener:
    removeEventListener:
    onerror:
    onsuccess:
    readonly readyState: 
    readonly result: 
    readonly source: 
    readonly transaction:
}
IDBDatabase{
    onabort: 
    onclose: 
    onerror:
    onversionchange:
    transaction:
    addEventListener:
    removeEventListener:
    deleteObjectStore:
    close:
    createObjectStore:
    readonly version:
}
IDBTransaction{
    readonly db: 
    readonly durability: 
    readonly error: 
    readonly mode: 
    readonly objectStoreNames: 
    onabort: 
    oncomplete: 
    onerror: 
    abort(): 
    commit(): 
    objectStore:
    addEventListener:
    removeEventListener:
}


Enter fullscreen mode Exit fullscreen mode

simple diagram to show how to open the database and do simple crud operations as you can see all operations follow the same pattern doing action and then listening to the INDRequst for success or other response
indexeddb_diagram

1. Open a database and creating store

The open operation doesn't open the database right away or start a transaction right away it returns an object of type IDBOpenDBRequest in success and throws an error incase of an error.

most operation work the same way the return some type of IDBRequest for which u have to listen to success or error.



const request = window.indexedDB.open("databasename", 1);
request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
    const db = request.result;
    if (!db.objectStoreNames.contains(storeName)) {
        // creating store if it doesnot exist
        db.createObjectStore(storeName);
    }
};
request.onsuccess = (e) => {
    console.log(e);  
};
request.onerror = (e) => {
    console.error(e);
}


Enter fullscreen mode Exit fullscreen mode

2. getting access to the database and store



const db = request.result; // the request from the indexedDB.open()
const transaction = db.transaction(param.storename, 'readwrite');
const store = transaction.objectStore(param.storename);


Enter fullscreen mode Exit fullscreen mode

3. doing crud operations

3.1 adding data



let request = store.add(data, key)
if (request) {
request.onsuccess = () => {
 // success
};
request.onerror = (e) => {
    throw new Error(e);
};


Enter fullscreen mode Exit fullscreen mode

3.2 deleting data



const request = store.delete(param.data.key);
request.onsuccess = () => {
 // success
};
request.onerror = (e) => {
    throw new Error(e);
};


Enter fullscreen mode Exit fullscreen mode

3.3 modifying data



const request = store.put(data, key);
request.onsuccess = () => {
 // success
};
request.onerror = (e) => {
    throw new Error(e);
};
);


Enter fullscreen mode Exit fullscreen mode

3.4 getting specific collection data

indexedDb offer a way to have access to data at the same time the database is searching through the database store.openCursor

3.4.1 fetching all store data



let data = [];
store.openCursor().onsuccess = (event) => {
try {
const cursor = event.target.result;
if (cursor) {
data.push({ value: cursor.value, key: cursor.key });
cursor.continue();
} else {
console.log('finished');
}
} catch (e) {
 throw new Error(e);
}
};


Enter fullscreen mode Exit fullscreen mode

you can convert all operation to asyncronous function for easy use
converting adding data to return a promise



const addData = async (db, storename, data, key) => {
    const transaction = db.transaction(param.storename, 'readwrite');
    const store = transaction.objectStore(param.storename);
    let request = store.add(data, key)
    if (request) {
    request.onsuccess = () => {
     // success
    };
    request.onerror = (e) => {
        throw new Error(e);
    };
}
await addData(db, "storename" , {/*somedata*/}, "key").


Enter fullscreen mode Exit fullscreen mode

full code converted to async funciton at github

Top comments (4)

Collapse
 
matias_affolter profile image
Matias Affolter

I've been into indexedDB recently but I use it in conjunction with localstorage because it doesn't need initialisation. #LacertaDB

Collapse
 
anasmustafa123 profile image
Anas Mustafa

i do that as well as it makes sense to use local storage for smaller data that u need frequently as it's faster.

Collapse
 
anasmustafa123 profile image
Anas Mustafa • Edited

u can also use libary like dexie to simplify the usage of indexeDB

Collapse
 
matias_affolter profile image
Matias Affolter

Ok