Introduction
The IndexedDB
, a new HTML5 web database which allows HTML5 web application to store data inside a user’s browser. The IndexedDB
is more powerful and useful for applications which requires to store a large amount of data on client side or web browser like Chrome, Internet Explorer, Firefox, etc. In this article, I’ll explain some basic concepts about it.
What is IndexedDB?
IndexedDB
, a new HTML5 data storage to store/manipulate data on client-side. This makes the application to load faster and more responsive than ever. It is not the same as a relational database, which has tables, with records. It affects the way that we design and build our applications. IndexedDB
creates an object store for a type of data and simply persist JavaScript objects to that store. Each object store can have a collection of Indexes that make it efficient to query and iterate across. This tutorial gives you a real-world example of how to use IndexedDB
in any web application.
Get Started
We need to include the following prefixes of implementation.
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
if (!indexedDB) {
alert("Your browser doesn't support a stable version of IndexedDB.")
}
Opening an IndexedDB
Before we create the database, we first need to create some data for the database. Suppose we have some customer information as shown below:
var userData = [
{ id: "1", name: "Tapas", age: 33, email: "tapas@example.com" },
{ id: "2", name: "Bidulata", age: 55, email: "bidu@home.com" }
];
Now we need to open our database using the open()
method as shown below::
var db;
var request = indexedDB.open("databaseName", 1);
request.onerror = function(e) {
console.log("error: ", e);
};
request.onsuccess = function(e) {
db = request.result;
console.log("success: "+ db);
};
request.onupgradeneeded = function(e) {
}
As you see above, we have opened a database with the name “databaseName
” and the version of the database. The open()
method accepts 2 parameters:
- 1st Param: name of the database. It checks whether the database named “
databaseName
” already exists or not, if it does not exist, then it will open the database, else it will create a new one. - 2nd Param: version of the database, which allows the user to update the schema of the database.
Onsuccess Handler
A success event “onsuccess
” is fired, if everything succeeds with request as its target and we saved the request’s result for later use by assigning it to db variable.
Onerror Handler
An error event “onerror
” is fired, if the process of opening database fail.
Onupgradeneeded Handler
If you want to update the database (or to create, delete or modify the database), then you have to implement the onupgradeneeded
handler that allows you to make any changes on the database. The “onupgradeneeded
” handler is the only place to alter the structure of database.
Creating & Adding Data to the Table
IndexedDB
uses object stores to store data rather than tables. Whenever a value is stored in an object store, it is associated with a key. It allows us to create indices on any object store. An index allows us to access the values stored in object store. The below code shows how we create the object store and insert the pre-prepared data into it:
request.onupgradeneeded = function(event) {
var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});
for (var i in userData) {
objectStore.add(userData[i]);
}
}
We create an object store using createObjectStore()
method. This method accepts 2 parameters: – name of the store and a parameter object. Here, we have named the object store as “users” and defined a keyPath
which is the property that makes an individual object in the store unique. Here, we have used the “id
” as keyPath
, which is a unique value in the object store, and we must make sure that the “id
” property must be present in every object in the object store. Once the object store is created, we can start adding the data into it using for
loop.
Manually Adding Data to the Table
We can manually add extra data into the database.
function Add() {
var request = db.transaction(["users"], "readwrite").objectStore("users")
.add({ id: "3", name: "Gautam", age: 30, email: "gautam@store.org" });
request.onsuccess = function(e) {
alert("Gautam has been added to the database.");
};
request.onerror = function(e) {
alert("Unable to add the information.");
}
}
Before we do any CRUD operation (read, write, modify) to our database, we have to use a transaction. The transaction()
method is used to specify which object stores we want the transaction to span. The transaction()
method accepts 3 parameters (second and third are optional). 1st is the list of object store we want to deal with, 2nd is whether we want to read only / read and write to the object, and the 3rd is the version change.
Retrieving Data from the Table
get()
method is used to retrieve the data from the object store. As we already set the id of object as keyPath
earlier, so the get()
method will look up the object that has the same id value. This will return us the object named “Bidulata
”.
function Read() {
var objectStore = db.transaction(["users"]).objectStore("users");
var request = objectStore.get("2");
request.onerror = function(event) {
alert("Unable to retrieve data from database!");
};
request.onsuccess = function(event) {
if(request.result) {
alert("Name: " + request.result.name + ", Age: " +
request.result.age + ", Email: " + request.result.email);
} else {
alert("Bidulata couldn't be found in your database!");
}
};
}
Retrieving All Data from the Table
The below method retrieves all data from the object source. Here, we are using cursor to retrieve all data from object store:
function ReadAll() {
var objectStore = db.transaction("users").objectStore("users");
var req = objectStore.openCursor();
req.onsuccess = function(event) {
db.close();
var res = event.target.result;
if (res) {
alert("Key " + res.key + " is " + res.value.name + ", Age: " +
res.value.age + ", Email: " + res.value.email);
res.continue();
}
};
req.onerror = function (e) {
console.log("Error Getting: ", e);
};
}
The openCursor()
is used to iterate over multiple records in a database. The continue()
function is used to continue with the next iteration in the loop.
Removing a Record from the Table
The below method removes a record from the object source.
function Remove() {
var request = db.transaction(["users"],
"readwrite").objectStore("users").delete("1");
request.onsuccess = function(event) {
alert("Tapas's entry has been removed from your database.");
};
}
We have to pass the keyPath
of the object that we want to remove as parameter to the delete()
method.
Final Code
The below method removes a record from the object source.
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IndexedDB</title>
<script type="text/javascript">
var indexedDB = window.indexedDB || window.mozIndexedDB ||
window.webkitIndexedDB || window.msIndexedDB;
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
if (!indexedDB) {
alert("Your browser doesn't support a stable version of IndexedDB.")
}
var customerData = [
{ id: "1", name: "Tapas", age: 33, email: "tapas@example.com" },
{ id: "2", name: "Bidulata", age: 55, email: "bidu@home.com" }
];
var db;
var request = indexedDB.open("newDatabase", 1);
request.onerror = function(e) {
console.log("error: ", e);
};
request.onsuccess = function(e) {
db = request.result;
console.log("success: "+ db);
};
request.onupgradeneeded = function(event) {
}
request.onupgradeneeded = function(event) {
var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});
for (var i in userData) {
objectStore.add(userData[i]);
}
}
function Add() {
var request = db.transaction(["users"], "readwrite")
.objectStore("users")
.add({ id: "3",
name: "Gautam", age: 30, email: "gautam@store.org" });
request.onsuccess = function(e) {
alert("Gautam has been added to the database.");
};
request.onerror = function(e) {
alert("Unable to add the information.");
}
}
function Read() {
var objectStore = db.transaction("users").objectStore("users");
var request = objectStore.get("2");
request.onerror = function(event) {
alert("Unable to retrieve data from database!");
};
request.onsuccess = function(event) {
if(request.result) {
alert("Name: " + request.result.name + ", Age: " +
request.result.age + ", Email: " + request.result.email);
} else {
alert("Bidulata couldn't be found in your database!");
}
};
}
function ReadAll() {
var objectStore = db.transaction("users").objectStore("users");
var req = objectStore.openCursor();
req.onsuccess = function(event) {
db.close();
var res = event.target.result;
if (res) {
alert("Key " + res.key + " is " + res.value.name + ",
Age: " + res.value.age + ", Email: " + res.value.email);
res.continue();
}
};
req.onerror = function (e) {
console.log("Error Getting: ", e);
};
}
function Remove() {
var request = db.transaction(["users"], "readwrite").objectStore("users").delete("1");
request.onsuccess = function(event) {
alert("Tapas's entry has been removed from your database.");
};
}
</script>
</head>
<body>
<button onclick="Add()">Add record</button>
<button onclick="Remove()">Delete record</button>
<button onclick="Read()">Retrieve single record</button>
<button onclick="ReadAll()">Retrieve all records</button>
</body>
</html>