Start · Sprachen · JavaScript · Referenz · IDBCursorWithValue.value

IDBCursorWithValue.value

Eigenschaft

Schreibgeschützte Eigenschaft, die den Wert des Datensatzes an der aktuellen Cursor-Position liefert, als strukturierten Klon des gespeicherten Objekts.

seit JavaScript Baseline: alle modernen Browser (IndexedDB 2.0) Kategorie: webapi

Signatur

IDBCursorWithValue.value

Beschreibung

IDBCursorWithValue.value liefert den Wert des Datensatzes, auf dem der Cursor gerade steht. Das kann jeder Wert sein, den der Structured-Clone-Algorithmus speichern kann: Objekte, Arrays, Strings, Zahlen, Date, Blob, Map und weitere.

Ein IDBCursorWithValue entsteht durch IDBObjectStore.openCursor() oder IDBIndex.openCursor(). Die Methoden openKeyCursor() liefern dagegen nur ein IDBCursor ohne value. Dieser Cursor ist schneller, wenn man nur Schlüssel braucht.

Bei jedem Schritt mit cursor.continue() oder cursor.advance(n) bekommt value den Wert des nächsten Datensatzes. Der zurückgegebene Wert ist eine Kopie. Wenn du ihn änderst, bleibt die Datenbank unverändert, bis du die Änderung mit cursor.update(value) oder store.put() zurückschreibst.

Typische Einsätze: alle Datensätze durchlaufen und filtern, Einträge nach Bedingungen ändern oder löschen und seitenweise Ausgaben über einen Index.

Rückgabewert

Typ
any
Beschreibung
Der Wert des aktuellen Datensatzes als strukturierter Klon, also eine Kopie. Das ist meist ein Objekt, kann aber jeder klonbare Wert sein.

Beispiele

Alle Datensätze eines Object Stores ausgeben

const request = indexedDB.open('shop', 1);

request.onupgradeneeded = () => {
  const db = request.result;
  const store = db.createObjectStore('produkte', { keyPath: 'id' });
  store.put({ id: 1, name: 'Tastatur', preis: 49 });
  store.put({ id: 2, name: 'Maus', preis: 19 });
};

request.onsuccess = () => {
  const db = request.result;
  const store = db.transaction('produkte', 'readonly').objectStore('produkte');

  store.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (!cursor) {
      console.log('Fertig');
      return;
    }
    const { name, preis } = cursor.value;
    console.log(`${cursor.key}: ${name} – ${preis} €`);
    cursor.continue();
  };
};
1: Tastatur – 49 € 2: Maus – 19 € Fertig

Werte ändern und mit update() zurückschreiben

const erhoehePreise = (db, prozent) => new Promise((resolve, reject) => {
  const tx = db.transaction('produkte', 'readwrite');
  const store = tx.objectStore('produkte');

  store.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (!cursor) return;

    // value ist eine Kopie: ändern allein reicht nicht
    const produkt = { ...cursor.value };
    produkt.preis = Math.round(produkt.preis * (1 + prozent / 100));
    cursor.update(produkt); // erst jetzt wird gespeichert
    cursor.continue();
  };

  tx.oncomplete = () => resolve();
  tx.onerror = () => reject(tx.error);
});

// Aufruf: await erhoehePreise(db, 10);

Datensätze mit async/await in ein Array sammeln

const alleWerte = (store, filter = () => true) => new Promise((resolve, reject) => {
  const ergebnis = [];
  const req = store.openCursor();
  req.onsuccess = () => {
    const cursor = req.result;
    if (!cursor) return resolve(ergebnis);
    if (filter(cursor.value)) ergebnis.push(cursor.value);
    cursor.continue();
  };
  req.onerror = () => reject(req.error);
});

// Nutzung:
// const store = db.transaction('produkte').objectStore('produkte');
// const guenstig = await alleWerte(store, (p) => p.preis < 30);
// console.log(guenstig);
[{ id: 2, name: 'Maus', preis: 19 }]

// Wichtig · Fallstricke

  • Nur lesbar: Eine Zuweisung an cursor.value hat keine Wirkung. Um einen Datensatz zu ändern, nutze cursor.update(neuerWert). Das geht nur in einer readwrite-Transaktion.
  • Kopie statt Referenz: Änderungen am zurückgegebenen Objekt werden nicht automatisch gespeichert. Klassen-Instanzen verlieren beim Klonen ihren Prototyp und kommen als einfache Objekte zurück.
  • Cursor-Typ: Cursor aus openKeyCursor() sind reine IDBCursor-Objekte und haben kein value, es ist dann undefined. Wenn du nur Schlüssel brauchst, ist das schneller.
  • Transaktion aktiv halten: Rufe continue() synchron im onsuccess-Handler auf. Ein await auf ein fremdes Promise dazwischen kann die Transaktion beenden. Danach gibt es einen TransactionInactiveError.
  • Performance: Wenn du alle Werte ohne Filterlogik brauchst, ist IDBObjectStore.getAll() meist deutlich schneller als ein Cursor.
  • Kompatibilität: Wird in allen modernen Browsern und in Web Workern unterstützt. In privaten Fenstern mancher Browser kann IndexedDB eingeschränkt sein.