Angular IndexedDB Wrapper
ngx-indexed-db is an Angular service that provides a reactive, observable-based wrapper around the browser's IndexedDB API. It simplifies database interactions for Angular applications, supporting both client-side rendering (CSR) and server-side rendering (SSR) since version 19.2.0. The current stable version is 22.0.0. While the exact release cadence isn't explicitly stated, the version numbers often align with Angular's major releases, suggesting active development. Key differentiators include its observable-driven API, full SSR compatibility, and the ability to provide custom IndexedDB implementations via an injection token for enhanced testing or non-browser environments. It also features a robust migration system for evolving database schemas.
Common errors
-
Error: No `indexedDB` object found in `window`.
cause This typically occurs when running an Angular application with SSR without proper `ngx-indexed-db` configuration for the server environment, or when using an older version that lacked full SSR support.fixUpgrade to `ngx-indexed-db@19.2.0` or newer. Ensure your SSR setup correctly uses `platform-server` and `ngx-indexed-db` is configured, potentially providing a custom `SERVER_INDEXED_DB` token if needed. -
DOMException: The database is not compatible with the version provided.
cause The `version` specified in `DBConfig` is lower than the version of the database already existing in the user's browser, or a version was incremented without providing the necessary migration functions.fixAlways increment the `DBConfig.version` when making schema changes. Ensure that a corresponding migration function exists in `migrationFactory` for each version increment that needs to apply schema changes or data transformations. -
DOMException: TransactionInactiveError: A request was placed against an IDBObjectStore, but the transaction which was used to retrieve it has since become inactive or finished.
cause An attempt was made to use an `IDBObjectStore` or `IDBIndex` object after the transaction it belongs to has completed, committed, or aborted. This usually means trying to perform an operation outside the scope of an active transaction.fixEnsure all database operations are completed within the lifetime of a single IndexedDB transaction. `ngx-indexed-db`'s service methods manage transactions, so avoid holding references to `objectStore` or `index` objects from a finished transaction. -
NG0304: 'NgxIndexedDBModule' is not an NgModule
cause This error can occur if `NgxIndexedDBModule` is imported incorrectly, or if there's a version mismatch between `@angular/core` and `ngx-indexed-db` that causes compilation issues.fixVerify that `@angular/core` and `ngx-indexed-db` versions are compatible. Ensure `NgxIndexedDBModule.forRoot(dbConfig)` is placed correctly in the `imports` array of an NgModule, or use `provideIndexedDb(dbConfig)` in your providers if using standalone components/bootstrap.
Warnings
- breaking Major version upgrades often coincide with Angular's ecosystem, requiring updates to maintain compatibility. Always check peer dependency ranges and release notes when upgrading Angular.
- gotcha Prior to version 19.2.0, `ngx-indexed-db` did not fully support Server-Side Rendering (SSR) and could lead to errors related to `window.indexedDB` being undefined. SSR is fully supported from v19.2.0 onwards.
- gotcha Database schema changes (e.g., adding new object stores or indexes) require incrementing the `DBConfig.version` and providing a `migrationFactory`. Failing to do so will result in `DOMException` errors when opening the database.
- gotcha IndexedDB operations are asynchronous and transaction-based. Mismanaging transactions or attempting operations outside an active transaction will lead to errors.
Install
-
npm install ngx-indexed-db -
yarn add ngx-indexed-db -
pnpm add ngx-indexed-db
Imports
- NgxIndexedDBModule
const NgxIndexedDBModule = require('ngx-indexed-db')import { NgxIndexedDBModule } from 'ngx-indexed-db' - DBConfig
import type { DBConfig } from 'ngx-indexed-db'import { DBConfig } from 'ngx-indexed-db' - provideIndexedDb
import { provideIndexedDb } from 'ngx-indexed-db' - NgxIndexedDBService
import { NgxIndexedDBService } from 'ngx-indexed-db' - SERVER_INDEXED_DB
import { SERVER_INDEXED_DB } from 'ngx-indexed-db'
Quickstart
import { NgModule, ApplicationConfig } from '@angular/core';
import { NgxIndexedDBModule, provideIndexedDb, DBConfig } from 'ngx-indexed-db';
// Ahead of time compiles requires an exported function for factories
export function migrationFactory() {
return {
1: (db, transaction) => {
const store = transaction.objectStore('people');
store.createIndex('country', 'country', { unique: false });
},
3: (db, transaction) => {
const store = transaction.objectStore('people');
store.createIndex('age', 'age', { unique: false });
}
};
}
const dbConfig: DBConfig = {
name: 'MyDb',
version: 3,
objectStoresMeta: [{
store: 'people',
storeConfig: { keyPath: 'id', autoIncrement: true },
storeSchema: [
{ name: 'name', keypath: 'name', options: { unique: false } },
{ name: 'email', keypath: 'email', options: { unique: false } }
]
}, {
store: 'animals',
storeConfig: { keyPath: 'id', autoIncrement: true },
storeSchema: [
{ name: 'name', keypath: 'name', options: { unique: true } }
]
}],
migrationFactory
};
// For NgModule-based applications
@NgModule({
imports: [
NgxIndexedDBModule.forRoot(dbConfig)
]
})
export class AppModule { }
// For Standalone API (main.ts or component providers)
const appConfig: ApplicationConfig = {
providers: [
provideIndexedDb(dbConfig)
]
};