Debugging IndexedDB Applications

IndexedDB is a
W3C Working Draft that enables JavaScript developers to store, search, and retrieve data on the user’s local client,
even when
Internet connectivity is disabled. This blog post describes IDBExplorer, a tool we use internally to debug IndexedDB applications. IDBExplorer lets you view
database schemas, object store content, and index details.

Exploring the tool with an example IndexedDB App

To illustrate, I created an application that tracks my New
Year’s resolutions using IndexedDB. It stores and accesses my resolutions locally (on the system browsing the Web page)
and lets me add or edit them. The “Done That!” button removes the selected resolution from the list and removes its internal
representation from the database.

Partial screen shot of an application that tracks New Year’s resolutions using IndexedDB.

IndexedDB defines a database as a container of information. Each database contains object stores, which are
repositories for JavaScript objects. Each object contains attributes which can be queried using the API. If you’re familiar
with relational databases, object stores can be equated to tables and each JavaScript object in an object store represents
a record. However, the objects stored in an IndexedDB object store are treated as opaque entities. In addition, these objects
do not have to contain the same properties.

If a JavaScript object is analogous to a relational database record, then the properties of that object can be thought of
as columns (or fields) in a table. As a result, IndexedDB allows you to define indexes that identify object properties that
can be used to search the records in an object store. Thus, indexes allow you to traverse and search IndexedDB data using
the attribute values on a JavaScript object.

IndexedDB allows each Domain to have multiple databases. This
example uses one database: “NewYear.” The app stores my resolutions in an object store named “Resolutions” inside the
NewYear database. Each resolution is a JavaScript object with the following attributes:

  • priorityId: Separates resolutions into different priorities
  • name: Name of the resolution
  • occurrenceId: Tracks how frequently the action of the resolution must be performed
  • dueDate: Completion date of the resolution
  • createdDate: Internal date when the resolution was added to the object store
  • categoryId: Defines the type of activity for a resolution

Notice that not all attributes are visible from the application’s UI. In some cases, they are only internally used (e.g.
createdDate).

Here’s how the IDBExplorer tool displays the contents of the “Resolutions” object store:

Partial screen shot of the IDBExplorer tool displaying the contents of the “Resolutions” object store.

The “Resolutions” object store also contains an index on the priorityId attribute named “priorityId,” which allows
the app to query objects using the priorityId property. The descriptions for the each priorityId value can
be found inside the “Priorities” object store and the descriptions for the occurrenceId values can be found inside
the “Occurrences” object store. Likewise, the descriptions for the categoryId values can be found inside the “Categories”
object store.

The tool uses a tree hierarchy to illustrate these relationships:

Screen shot of the IDBExplorer tool showing there are five resolutions in the database.

The IDBExplorer tool shows there are five resolutions in my database (two high priority tasks, two medium priorities, and
one low priority).

Using the application, I can add a new resolution:

Partial screen shot of the New Year’s Resolutions application showing adding a resolution.

The app retrieves the values for Occurrence, Priority, and Category fields from their respective object
stores using cursors and displays them to the user. The IDBExplorer tool lets you see how these values exist in the object
store. For example, selecting the Categories object store displays the available categories and their descriptions:

Screen shot of the IDBExplorer tool showing how values exist in the object store.

You can update a resolution by selecting it in the “WorkOn” screen and choosing “Edit.” After making any changes, selecting
the “Update” button will commit the changes and update the values in the “Resolutions” object store.

Partial screen shot of the New Year’s Resolutions application showing updating a resolution by selecting it in using the “WorkOn” screen.

Using IDBExplorer in your Applications

You can include the IDBExplorer tool in your Metro style app or Web site. However, we recommend you not deploy the tool with
your app.

To add the tool to your site, copy and unzip the content of the
IDBExplorer package into your site. Your application will need to link to the IDBExplorer.html file contained inside
the IDBExplorer folder using either an iframe element or a new window.

In our example, we decided to host IDBExplorer inside an iframe element. . However, for normal development we recommend hosting
this URI inside a new window. This will allow you to have a side-by-side experience when debugging your database and application
without affecting your site’s user interface.

When hosting IDBExplorer, you need to pass the database name using the query string. In this example, this was done using
the src attribute of the iframe element:

<iframe
id
="debuggerId" class="debuggerContainer"
src="IDBExplorer/IDBExplorer.html?name=NewYear"></iframe>

When planning to host this functionality in a Metro style app, remember that Metro-style apps run fullscreen. As a result,
you should navigate to this URL, rather than opening a new window (you will need to add a Back button to the IDBExplorer.html
file in order to be able to return to your application). Alternatively, you can add an iframe element and display the tool
in it.

Enjoy the tool and let us know what you think!

—Israel Hilerio, Ph.D., Principal Program Manager, Internet Explorer


IEBlog