Start · Sprachen · JavaScript · Referenz · IDBObjectStore.getAll()

IDBObjectStore.getAll()

Methode

Liest alle Datensätze eines Object Stores, optional gefiltert nach Schlüssel oder <code>IDBKeyRange</code> und begrenzt auf eine Höchstanzahl, als Array aus.

seit JavaScript Baseline: alle modernen Browser (seit 2016/2017) Kategorie: webapi

Signatur

IDBObjectStore.prototype.getAll(query, count)

Beschreibung

getAll() gibt ein IDBRequest zurück. Bei Erfolg enthält dessen result ein Array mit allen Werten des Object Stores, die zum Parameter query passen. Ohne Parameter werden alle Datensätze geliefert. Sie sind aufsteigend nach Primärschlüssel sortiert.

Die Methode ist deutlich bequemer und meist auch schneller als ein Cursor über openCursor(), weil nicht für jeden Datensatz ein eigenes success-Ereignis ausgelöst wird. Sie eignet sich gut, um kleine bis mittelgroße Datenmengen komplett in den Speicher zu laden, etwa zum Rendern einer Liste oder zum Befüllen eines Caches beim Start der Anwendung.

Mit query (ein einzelner Schlüssel oder ein IDBKeyRange) lässt sich ein Schlüsselbereich auswählen, mit count die Anzahl der Ergebnisse begrenzen. Zusammen ergibt das eine einfache Seitenaufteilung (Pagination). Brauchst du nur die Schlüssel, ist getAllKeys() sparsamer. Willst du nach anderen Feldern filtern, rufst du getAll() auf einem IDBIndex auf.

Parameter

Name Typ Default Beschreibung
$query any | IDBKeyRange | null undefined (alle Datensätze) Ein gültiger Schlüssel oder ein IDBKeyRange, der die zurückgegebenen Datensätze eingrenzt. null oder undefined bedeutet: keine Einschränkung.
$count number unbegrenzt Höchstanzahl der zurückgegebenen Werte, eine ganze Zahl von 0 bis 232−1. Bei 0 oder ohne Angabe gibt es keine Begrenzung. Werte außerhalb dieses Bereichs lösen einen TypeError aus.

Rückgabewert

Typ
IDBRequest<any[]>
Beschreibung
Ein IDBRequest. Bei Erfolg enthält request.result ein Array mit den passenden Werten, das bei keinem Treffer leer ist. Im Fehlerfall wird das Ereignis error ausgelöst.

Beispiele

Alle Datensätze laden (Promise-Wrapper)

const openDb = () => new Promise((resolve, reject) => {
  const req = indexedDB.open('shop', 1);
  req.onupgradeneeded = () => {
    const store = req.result.createObjectStore('produkte', { keyPath: 'id' });
    store.add({ id: 1, name: 'Tastatur', preis: 49 });
    store.add({ id: 2, name: 'Maus', preis: 19 });
    store.add({ id: 3, name: 'Monitor', preis: 199 });
  };
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const getAllProdukte = async () => {
  const db = await openDb();
  return new Promise((resolve, reject) => {
    const req = db.transaction('produkte', 'readonly')
      .objectStore('produkte')
      .getAll();
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
};

const produkte = await getAllProdukte();
console.log(produkte.map(p => p.name));
["Tastatur", "Maus", "Monitor"]

Schlüsselbereich mit IDBKeyRange abfragen

const db = await openDb(); // aus Beispiel 1
const store = db.transaction('produkte').objectStore('produkte');

// Nur IDs von 2 bis 3 (inklusive)
const req = store.getAll(IDBKeyRange.bound(2, 3));
req.onsuccess = () => {
  console.log(req.result.map(p => `${p.id}: ${p.name}`));
};
["2: Maus", "3: Monitor"]

Seitenweise laden mit count

const ladeSeite = (db, abId, seitenGroesse) => new Promise((resolve, reject) => {
  const store = db.transaction('produkte').objectStore('produkte');
  // lowerBound(abId, true) = alle IDs größer als abId
  const range = abId == null ? null : IDBKeyRange.lowerBound(abId, true);
  const req = store.getAll(range, seitenGroesse);
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const db = await openDb();
const seite1 = await ladeSeite(db, null, 2);
const seite2 = await ladeSeite(db, seite1.at(-1).id, 2);
console.log(seite1.length, seite2.map(p => p.name));
2 ["Monitor"]

// Wichtig · Fallstricke

  • Speicherbedarf: Alle Treffer werden auf einmal in den Speicher geladen. Bei sehr großen Stores solltest du deshalb mit count seitenweise arbeiten oder openCursor() verwenden.
  • Die Methode wirft sofort eine TransactionInactiveError, wenn die Transaktion schon beendet ist. Das passiert oft, wenn zwischen dem Öffnen der Transaktion und dem Aufruf ein await auf etwas anderes als eine IndexedDB-Anfrage steht. Ist der Object Store gelöscht, kommt eine InvalidStateError. Bei einem ungültigen Schlüssel oder Bereich kommt eine DataError.
  • Ein Treffer mit dem Wert undefined lässt sich im Ergebnis-Array nicht von einem fehlenden Eintrag unterscheiden. Ob ein Schlüssel existiert, prüfst du deshalb mit count() oder getAllKeys().
  • Die Sortierung folgt immer aufsteigend dem Primärschlüssel. Eine absteigende Reihenfolge ist nur über einen Cursor mit 'prev' möglich, oder du drehst das Array danach mit reverse() um.
  • Die Methode ist in allen modernen Browsern verfügbar, im alten Internet Explorer 11 jedoch nicht. IndexedDB ist außerdem an den Ursprung (Origin) gebunden und im privaten Modus einiger Browser eingeschränkt.