DEV Community

Andrés Valdivia Cuzcano
Andrés Valdivia Cuzcano

Posted on

Create a database with IndexedBD

Before opening (creating) a database using IndexedDB we must verify that the browser has the necessary support, for this we create a function that we will use later when creating the database:

function indexedDBSupport(){
    return 'indexedDB' in window;
}
Enter fullscreen mode Exit fullscreen mode

Then we have to create a request to open the database that returns an event (success or error) through the IDBOpenDBRequest object, which will allow us to access the event.

The open(name, version) function has two parameters, the first is the name of the database that identifies it within the client's browser, the second parameter is the version of our database, this is important since it will be defined a Database Schema that will determine the structure of the objects to be stored, so if you want to change it, you just have to change the version of our database.

// The version value is 1 by default
const request = window.indexedDB.open("MyDatabase", 1);
Enter fullscreen mode Exit fullscreen mode

Event handling

As mentioned above, once the request to open the database has been made, 3 events can be handled with their respective functions:

  • onerror: If the creation or connection to the database fails.
  • onsuccess: This is executed every time the database is connected or created.

  • onupgradeneeded: This is executed only once, when the database is created or updated, so the structure of it (Database Schema) will be defined here.

💡 Once the request is made, we obtain the IDBOpenDBRequest object, in which the result of said request is stored.

// Save the connection to the database in a global variable
// since it will later be used to carry out transactions
let db;

function createDatabase() {

    if (!indexedDBSupport()) throw new Error("Your browser doesn't support IndexedBD");

    const request = window.indexedDB.open('MyDatabase', 1);

// Event handling
    request.onerror = (e) => {
        console.error(`IndexedDB error: ${request.errorCode}`);
    };

    request.onsuccess = (e) => {
        console.info('Successful database connection');
        db = request.result;
    };

    request.onupgradeneeded = (e) => {
        console.info('Database created');
        const db = request.result;
        //...
    };

}
Enter fullscreen mode Exit fullscreen mode

Using onupgradeneeded

As mentioned above, this event is fired when the database is created for the first time or when its version is updated, so it is the ideal place to specify the Database Schema.

Creating an Object Store (table)

We must define where the objects will be stored for the current version of our database. For this we create an instance of IDBObjectStore (represents an object store) using the createObjectStore(name, options) method, which has the following parameters:

  • name: Name of the Object Store

  • options: Optional parameter that contains the following attributes:

    • keypath: Specifies the name of the attribute that will contain the index with which it will identify each object.
    • autoIncrement: If the value is true, an incremental value will be given to the keyPath.
//...

request.onupgradeneeded = (e) => {

    console.info('Database created');

    const db = request.result;

    const objectStore = db.createObjectStore('student', {keyPath: 'email'})
};

//...
Enter fullscreen mode Exit fullscreen mode

💡 If you want to update the Object Store, bear in mind that it will have the new structure, but it will be empty, so is a good idea that, before creating the new Object Store, save the objects in another place and then delete the old Object Store and reinsert them into the new one.

Creating Indexes (fields or attributes)

To create “fields” (index) in a "table" (Object Store), use the createIndex(indexName, keyPath, options) method of the IDBObjectStore object, which has the following parameters:

  • indexName: It is the name by which the "field" is identified within the table.

  • keyPath: It is the property of the object that will contain the value of the field. Most of the time the indexName and the keyPath have the same value, since it makes sense that the field is called the same as the property that will contain its value.

  • options: The most useful property is unique which does not allow duplicate values ​​within the same index.

//...

request.onupgradeneeded = (e) => {

    console.info('Database created');

    const db = request.result;

    const objectStore = db.createObjectStore('student', {keyPath: 'email'});

    // Indexes
    objectStore.createIndex("email", "email", { unique: true });
    objectStore.createIndex("name", "name", { unique: false });
    objectStore.createIndex("lastname", "lastname", { unique: false });
    objectStore.createIndex("age", "age", { unique: false });

};

//...
Enter fullscreen mode Exit fullscreen mode

As it works based on requests, we can use the complete event to verify that the transaction was completed and the Object Store was created successfully to perform some action later, if necessary.

//...

request.onupgradeneeded = (e) => {

    console.info('Database created');

    const db = request.result;

    const objectStore = db.createObjectStore('student', {keyPath: 'email'});

    // Indexes
    objectStore.createIndex('email', 'email', { unique: true });
    objectStore.createIndex('name', 'name', { unique: false });
    objectStore.createIndex('lastname', 'lastname', { unique: false });
    objectStore.createIndex('age', 'age', { unique: false });

    // Transaction completed
    objectStore.transaction.oncompleted = (e)=> {
        console.log('Object store "student" created');
    }

};

//...
Enter fullscreen mode Exit fullscreen mode

Discussion (0)