top of page
  • Writer's pictureAn Object Is A

Local Database and Chrome Extensions (IndexedDB)

Updated: Nov 9, 2021



 

This tutorial is based on Chrome Extension Manifest Version 2.


To demonstrate IndexedDB in the context of a Chrome Extension, we're going to use a simple HTML page with 2 forms.

  • One form for adding records.

  • One form for searching and editing records.


We'll use this form through the pop-up page of our Chrome Extension.


Let’s begin…

Our manifest file…
// manifest.json
{
    "name": "chrome ext with localDB",
    "description": "chrome ext interacting with IndexedDB",
    "version": "0.1.0",
    "manifest_version": 2,
    "icons": {
        "16": "./obj-16x16.png",
        "32": "./obj-32x32.png",
        "48": "./obj-48x48.png",
        "128": "./obj-128x128.png"
    },
    "background": {
        "scripts": [
            "./background.js"
        ]
    },
    "options_page": "./options.html",
    "browser_action": {
        "default_popup": "popup.html"
    },
    "permissions": []
}

Note: We don't need any special permissions; we don't need the storage permission to use IndexedDB.


Let's take a look at that background script!

When our Chrome Extension first installs, we create a database…

// background.js
let db = null;

function create_database() {
    const request = window.indexedDB.open('MyTestDB');

    request.onerror = function (event) {
        console.log("Problem opening DB.");
    }

    request.onupgradeneeded = function (event) {
        db = event.target.result;

        let objectStore = db.createObjectStore('roster', {
            keyPath: 'email'
        });

        objectStore.transaction.oncomplete = function (event) {
            console.log("ObjectStore Created.");
        }
    }

    request.onsuccess = function (event) {
        db = event.target.result;
        console.log("DB OPENED.");
        insert_records(roster);

        db.onerror = function (event) {
            console.log("FAILED TO OPEN DB.")
        }
    }
}

…then populate that database.

// background.js
function insert_records(records) {
    if (db) {
        const insert_transaction = db.transaction("roster", "readwrite");
        const objectStore = insert_transaction.objectStore("roster");

        return new Promise((resolve, reject) => {
            insert_transaction.oncomplete = function () {
                console.log("ALL INSERT TRANSACTIONS COMPLETE.");
                resolve(true);
            }

            insert_transaction.onerror = function () {
                console.log("PROBLEM INSERTING RECORDS.")
                resolve(false);
            }

            records.forEach(person => {
                let request = objectStore.add(person);

                request.onsuccess = function () {
                    console.log("Added: ", person);
                }
            });
        });
    }
}

When we get messages to add, get, update, or delete from the foreground..

// background.js
function get_record(email) {
    if (db) {
        const get_transaction = db.transaction("roster", "readonly");
        const objectStore = get_transaction.objectStore("roster");

        return new Promise((resolve, reject) => {
            get_transaction.oncomplete = function () {
            console.log("ALL GET TRANSACTIONS COMPLETE.");
            }

            get_transaction.onerror = function () {
            console.log("PROBLEM GETTING RECORDS.")
            }

            let request = objectStore.get(email);

            request.onsuccess = function (event) {
            resolve(event.target.result);
            }
        });
    }
}

function update_record(record) {
    if (db) {
        const put_transaction = db.transaction("roster", "readwrite");
        const objectStore = put_transaction.objectStore("roster");

        return new Promise((resolve, reject) => {
            put_transaction.oncomplete = function () {
                console.log("ALL PUT TRANSACTIONS COMPLETE.");
                resolve(true);
            }

            put_transaction.onerror = function () {
                console.log("PROBLEM UPDATING RECORDS.")
                resolve(false);
            }

            objectStore.put(record);
        });
    }
}

function delete_record(email) {
    if (db) {
        const delete_transaction = db.transaction("roster", 
        "readwrite");
        const objectStore = delete_transaction.objectStore("roster");

        return new Promise((resolve, reject) => {
            delete_transaction.oncomplete = function () {
                console.log("ALL DELETE TRANSACTIONS COMPLETE.");
                resolve(true);
            }

            delete_transaction.onerror = function () {
                console.log("PROBLEM DELETE RECORDS.")
                resolve(false);
            }

            objectStore.delete(email);
        });
    }
}

…we can respond with getting, updating, and deleting records…


Let's take a look at the pop-up page and its accompanying script.


The popup page is a basic html page. Two forms with buttons…


…and of course our popup-script.js attached so we can capture and manipulate the DOM.

It's in the popup-script.js that we capture form information and send messages to the background script, so the background script can execute all of the IndexedDB commands…


…and once we receive the IndexedDB data from our background, we go ahead and show the user some visual feedback on the HTML popup page!


Using A Local Database(IndexedDB) with A Google Chrome Extension


933 views0 comments

Recent Posts

See All
bottom of page