Signatur
Beschreibung
Die schreibgeschützte Eigenschaft objectStoreNames einer IDBDatabase-Instanz liefert eine DOMStringList mit den Namen aller Object Stores der verbundenen Datenbank. Die Namen sind alphabetisch sortiert, genauer nach der Reihenfolge der UTF-16-Codeeinheiten.
Wichtigster Einsatzort ist der upgradeneeded-Handler von indexedDB.open(). Dort prüft man mit db.objectStoreNames.contains(name), ob ein Store schon existiert, bevor man createObjectStore() aufruft. Wird ein bereits vorhandener Name noch einmal angelegt, wirft der Aufruf eine ConstraintError-DOMException. Mit derselben Prüfung lassen sich idempotente Migrationen über mehrere Schema-Versionen schreiben.
Eine DOMStringList ist kein Array. Sie bietet nur length, item(index), contains(string) und den Zugriff per Index. Sie ist aber iterierbar, deshalb funktionieren for...of, der Spread-Operator und Array.from(). Brauchst du Array-Methoden wie map() oder filter(), wandle die Liste vorher um.
Außerhalb einer Versionsänderung bleibt die Liste für die bestehende Verbindung gleich. Object Stores lassen sich nur während einer versionchange-Transaktion anlegen oder löschen.
Rückgabewert
length, item() und contains() und ist iterierbar.Beispiele
Object Store nur bei Bedarf anlegen (upgradeneeded)
const request = indexedDB.open('shop', 2);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Nur anlegen, wenn der Store noch fehlt – sonst ConstraintError
if (!db.objectStoreNames.contains('produkte')) {
db.createObjectStore('produkte', { keyPath: 'id' });
}
if (!db.objectStoreNames.contains('warenkorb')) {
db.createObjectStore('warenkorb', { autoIncrement: true });
}
};
request.onsuccess = (event) => {
const db = event.target.result;
console.log([...db.objectStoreNames]);
};
Alle Stores auflisten (Promise-Wrapper)
const openDB = (name) =>
new Promise((resolve, reject) => {
const req = indexedDB.open(name);
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const listStores = async (dbName) => {
const db = await openDB(dbName);
const names = Array.from(db.objectStoreNames);
console.log(`${db.name} v${db.version}: ${names.length} Stores`);
for (const name of names) console.log('–', name);
db.close();
return names;
};
listStores('shop');
Veralteten Store bei einer Migration entfernen
const req = indexedDB.open('shop', 3);
req.onupgradeneeded = (event) => {
const db = event.target.result;
if (db.objectStoreNames.contains('warenkorb')) {
db.deleteObjectStore('warenkorb');
}
if (!db.objectStoreNames.contains('bestellungen')) {
const store = db.createObjectStore('bestellungen', { keyPath: 'nr' });
store.createIndex('datum', 'datum');
}
console.log(db.objectStoreNames.length, db.objectStoreNames.item(0));
};
Transaktion über alle Stores öffnen
const clearAll = (db) =>
new Promise((resolve, reject) => {
// DOMStringList wird von transaction() direkt akzeptiert
const tx = db.transaction(db.objectStoreNames, 'readwrite');
for (const name of db.objectStoreNames) {
tx.objectStore(name).clear();
}
tx.oncomplete = () => resolve();
tx.onerror = () => reject(tx.error);
});
const req = indexedDB.open('shop');
req.onsuccess = async () => {
await clearAll(req.result);
console.log('Alle Stores geleert');
};
// Wichtig · Fallstricke
- Kein Array:
db.objectStoreNames.includes(),.map()oder.forEach()gibt es nicht. Nutzecontains()oder wandle die Liste mitArray.from()bzw.[...liste]um. - Leere Liste: Wenn
transaction()eine leere Liste bekommt (z. B. bei einer neuen Datenbank ohne Stores), wirft der Aufruf eineInvalidAccessError-DOMException. Prüfe deshalb vorherlength > 0. - Nur Momentaufnahme pro Verbindung: Wenn ein anderer Tab die Datenbank auf eine neue Version hebt, sieht die bestehende Verbindung die neuen Stores nicht. Schließe sie im
versionchange-Event und öffne sie neu. - Die Namen sind nach UTF-16-Codeeinheiten sortiert, nicht in der Reihenfolge, in der die Stores angelegt wurden. Großbuchstaben stehen deshalb vor Kleinbuchstaben.
- Die Eigenschaft wird in allen aktuellen Browsern unterstützt, auch in Web Workern. Im privaten Modus älterer Firefox-Versionen war IndexedDB nicht verfügbar.