Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion files/en-us/web/api/idbdatabase/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Listen to these events using `addEventListener()` or by assigning an event liste
- : An event fired when the database connection is unexpectedly closed.

- [`versionchange`](/en-US/docs/Web/API/IDBDatabase/versionchange_event)
- : An event fired when a database structure change was requested.
- : An event fired when another connection requested a structure change (an upgrade) or a deletion. Handler code should [close the database](/en-US/docs/Web/API/IDBDatabase/versionchange_event) so that the change is not blocked.

The following events are available to `IDBDatabase` via event bubbling from {{domxref("IDBTransaction")}}:

Expand Down
74 changes: 31 additions & 43 deletions files/en-us/web/api/idbdatabase/versionchange_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ browser-compat: api.IDBDatabase.versionchange_event

{{APIRef("IndexedDB")}}

The `versionchange` event is fired when a database structure change ([`upgradeneeded`](/en-US/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event) event send on an [`IDBOpenDBRequest`](/en-US/docs/Web/API/IDBOpenDBRequest) or [`IDBFactory.deleteDatabase`](/en-US/docs/Web/API/IDBFactory/deleteDatabase)) was requested elsewhere (most probably in
another window/tab on the same computer).
The `versionchange` event is fired when a database structure change ([`upgradeneeded`](/en-US/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event) event sent on an [`IDBOpenDBRequest`](/en-US/docs/Web/API/IDBOpenDBRequest)) or a deletion ([`IDBFactory.deleteDatabase`](/en-US/docs/Web/API/IDBFactory/deleteDatabase)) was requested from another connection — most probably another window or tab of the same page on the same computer.

An upgrade or deletion cannot proceed while other connections to the database are open: it waits until every other connection has been closed. Handling `versionchange` by calling {{domxref("IDBDatabase.close()")}} is the usual way to let it proceed; if the connection stays open, the request in the other tab stays pending until the connection is closed, for example when the user closes the tab.

If connections are still open after the `versionchange` events have been dispatched, the request that asked for the change receives a [`blocked`](/en-US/docs/Web/API/IDBOpenDBRequest/blocked_event) event. Once the remaining connections are closed, an upgrade continues with that request's [`upgradeneeded`](/en-US/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event) event. Code that keeps running after closing its connection should also expect that reopening the database with its old version number now fails with a `VersionError`, because the requested version is lower than the database's current version.

## Syntax

Expand All @@ -27,64 +30,49 @@ A generic {{domxref("Event")}}.

## Examples

This example opens a database and, on success, adds a listener to `versionchange`:
The important thing a `versionchange` handler can do is close the database, so that the tab that asked for the change is unblocked. A common pattern is to close the connection and tell the user to reload:

```js
// Open the database
const dBOpenRequest = window.indexedDB.open("Nonexistent", 4);
const dbOpenRequest = window.indexedDB.open("toDoList", 1);

dBOpenRequest.onupgradeneeded = (event) => {
dbOpenRequest.onsuccess = (event) => {
const db = event.target.result;
// Create an objectStore for this database
const objectStore = db.createObjectStore("toDoList", {
keyPath: "taskTitle",
});

// define what data items the objectStore will contain
objectStore.createIndex("hours", "hours", { unique: false });
objectStore.createIndex("minutes", "minutes", { unique: false });
objectStore.createIndex("day", "day", { unique: false });
objectStore.createIndex("month", "month", { unique: false });
objectStore.createIndex("year", "year", { unique: false });
};

dBOpenRequest.addEventListener("success", (event) => {
const db = event.target.result;
db.addEventListener("versionchange", (event) => {
console.log("The version of this database has changed");
});
});
db.onversionchange = () => {
// Another tab asked for a newer version. Close our connection so the
// other tab's upgradeneeded can run, then ask the user to reload.
db.close();
document.querySelector("p").textContent =
"A new version of this page is ready. Please reload or close this tab.";
};
};
```

The same example, using the `onversionchange` event handler property:
A tab that requests the change should show the state of the request to the user, so that a block on another tab is not mistaken for a failure:

```js
// Open the database
const dBOpenRequest = window.indexedDB.open("Nonexistent", 4);
const dbOpenRequest = window.indexedDB.open("toDoList", 2);

// Another tab still has the database open (it did not close its connection
// in response to versionchange), so the upgrade has to wait.
dbOpenRequest.onblocked = () => {
document.querySelector("p").textContent =
"Still waiting for other tabs to close the database.";
};

dBOpenRequest.onupgradeneeded = (event) => {
dbOpenRequest.onupgradeneeded = (event) => {
const db = event.target.result;
// Create an objectStore for this database
const objectStore = db.createObjectStore("toDoList", {
keyPath: "taskTitle",
});

// define what data items the objectStore will contain
objectStore.createIndex("hours", "hours", { unique: false });
objectStore.createIndex("minutes", "minutes", { unique: false });
objectStore.createIndex("day", "day", { unique: false });
objectStore.createIndex("month", "month", { unique: false });
objectStore.createIndex("year", "year", { unique: false });
db.createObjectStore("toDoList", { keyPath: "taskTitle" });
};

dBOpenRequest.onsuccess = (event) => {
dbOpenRequest.onsuccess = (event) => {
const db = event.target.result;
db.onversionchange = (event) => {
console.log("The version of this database has changed");
};
document.querySelector("p").textContent = "Version " + db.version;
};
```

See also [Version changes while a web app is open in another tab](/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#version_changes_while_a_web_app_is_open_in_another_tab) in the Using IndexedDB guide.

## Specifications

{{Specifications}}
Expand Down
Loading