Reputation: 715
If I have IndexedDB
database opened in multiple tabs, can I track data changes on all tabs without reloading?
Upvotes: 4
Views: 2975
Reputation: 18690
To extend what dumbmatter answered, here is how I achieved it with BroadcastChannel. If you are going for more support I suggest using postMessage instead of a BroadcastChannel.
function putThing(db, channel, thing) {
return new Promise(function(resolve, reject) {
const transaction = db.transaction('things', 'readwrite');
transaction.oncomplete = function(event) {
const message = {operation: 'updated', id: thing.id};
channel.postMessage(message);
resolve();
};
transaction.onerror = function(event) {
reject(event.target.error);
};
const store = transaction.objectStore('things');
store.put(thing);
});
}
// In tab where operation occurs
const db = await open(...);
const channel = new BroadcastChannel('myChannel');
await putThing(db, channel, thing);
channel.close();
db.close();
// In other tab where you want observation of changes
const channel = new BroadcastChannel('myChannel');
channel.onmessage = function(event) {
const message = event.data;
console.log('A message occurred', message);
};
A few points:
Upvotes: 4
Reputation: 9673
There's no built in way to do this with IndexedDB alone. You basically have two options:
Poll IndexedDB with some frequency and check for new values
Use some other way of cross-tab communication to send a signal that you need to check for new values from IndexedDB. For example localStorage (emits cross-tab events when something changes) or a BroadcastChannel (designed exactly for the purpose of cross-tab communication, but does not have perfect cross browser support).
Upvotes: 4