Signatur
Beschreibung
Mit update() überschreiben Sie den Datensatz, auf dem ein IDBCursor gerade steht. Die Methode arbeitet asynchron: Sie gibt sofort ein IDBRequest zurück, und das Ergebnis kommt später über dessen Ereignisse success oder error. Bei Erfolg enthält request.result den Schlüssel des aktualisierten Datensatzes.
Typischerweise nutzen Sie update() für Massenänderungen: Sie laufen mit openCursor() über einen Objekt-Store oder Index, prüfen oder verändern jeden Datensatz und schreiben ihn direkt zurück. So müssen Sie nicht erst alle Datensätze laden und danach einzeln mit put() speichern.
Voraussetzungen: Die Transaktion muss im Modus "readwrite" geöffnet sein. Der Cursor muss mit openCursor() erzeugt worden sein, nicht mit openKeyCursor(). Er muss außerdem gerade auf einem Datensatz stehen. Verwendet der Store Inline-Schlüssel (keyPath), darf sich der Primärschlüssel im neuen Wert nicht ändern.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | any | Der neue Wert für die aktuelle Cursor-Position. Er muss mit dem structured clone-Algorithmus kopierbar sein. Bei Inline-Schlüsseln muss der Schlüssel im Wert gleich bleiben. |
Rückgabewert
IDBRequest. Bei Erfolg enthält result den Primärschlüssel des aktualisierten Datensatzes.Beispiele
Alle Artikel einer Kategorie um 10 % verteuern
const request = indexedDB.open('shop', 1);
request.onsuccess = () => {
const db = request.result;
const tx = db.transaction('produkte', 'readwrite');
const store = tx.objectStore('produkte');
store.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return; // Keine weiteren Datensätze
const produkt = cursor.value;
if (produkt.kategorie === 'buecher') {
produkt.preis = Math.round(produkt.preis * 1.1 * 100) / 100;
const upd = cursor.update(produkt);
upd.onsuccess = () => console.log('Aktualisiert:', upd.result);
}
cursor.continue();
};
tx.oncomplete = () => console.log('Alle Preise angepasst');
};
Promise-Wrapper mit async/await
const promisify = (req) => new Promise((resolve, reject) => {
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const markiereAlleGelesen = (db) => new Promise((resolve, reject) => {
const tx = db.transaction('nachrichten', 'readwrite');
const index = tx.objectStore('nachrichten').index('gelesen');
let anzahl = 0;
// Nur ungelesene Nachrichten (gelesen === 0)
index.openCursor(IDBKeyRange.only(0)).onsuccess = (e) => {
const cursor = e.target.result;
if (!cursor) return;
promisify(cursor.update({ ...cursor.value, gelesen: 1 }))
.then(() => anzahl++);
cursor.continue();
};
tx.oncomplete = () => resolve(anzahl);
tx.onerror = () => reject(tx.error);
});
// Aufruf: const n = await markiereAlleGelesen(db);
// console.log(`${n} Nachrichten als gelesen markiert`);
Fehlerbehandlung bei geändertem Schlüssel
store.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return;
try {
// Store hat keyPath 'id' – Änderung des Schlüssels ist verboten
cursor.update({ ...cursor.value, id: cursor.value.id + 1000 });
} catch (err) {
console.error(err.name); // DataError
}
cursor.continue();
};
// Wichtig · Fallstricke
- Synchron ausgelöste Ausnahmen (sie kommen nicht über
onerror):TransactionInactiveError, wenn die Transaktion nicht mehr aktiv ist;ReadOnlyErrorbei einer"readonly"-Transaktion;InvalidStateErrorbei einem Schlüssel-Cursor (openKeyCursor()), bei gelöschtem Store oder wenn der Cursor gerade iteriert oder am Ende steht;DataError, wenn sich bei Inline-Schlüsseln der Primärschlüssel ändert;DataCloneErrorbei nicht klonbaren Werten wie Funktionen oder DOM-Knoten. - Transaktion nicht verlieren: Warten Sie zwischen
update()undcontinue()nicht auf fremde Promises wiefetchodersetTimeout. Die Transaktion schließt sich automatisch, sobald keine offenen Anfragen mehr bestehen. Danach werfen weitere AufrufeTransactionInactiveError. - Rufen Sie
update()auf, bevor Siecontinue()oderadvance()aufrufen. Danach steht der Cursor nicht mehr auf dem Datensatz. - Ändert
update()einen Wert, der für einen laufenden Index-Cursor relevant ist, wird der Datensatz im Index neu einsortiert. Er kann dann erneut besucht werden, wenn er in Laufrichtung nach vorn wandert. - Wird nur ein bekannter Datensatz geändert, ist
IDBObjectStore.put()einfacher.update()lohnt sich beim Durchlaufen vieler Datensätze. - Kompatibilität: Die Methode wird von allen modernen Browsern und in Web Workern unterstützt. Im privaten Modus älterer Safari-Versionen war IndexedDB eingeschränkt.