In the vast majority of cases, you'll manage independent apps (ie. each having its own data), and each using only one client-side storage API (e.g. a native API or this lib, but not both at the same time in one app).
In some special cases, it could happen:
- you share the same data between multiple apps on the same subdomain,
but not all apps are built with the same framework, so each one will use a different client-side storage API
(e.g. an Angular app using this lib and a non-Angular app using the
localForage
lib) - while not recommended, you could also mix several APIs inside the same app
(e.g. mixing native
indexedDB
and this lib).
If you're in one of these cases, please read this guide carefully, as there are important things to do and to be aware of to achieve interoperability.
If you started using this lib since version >= 9, you're good to go.
If you started using this lib before version 9, you need to check your AppModule
:
import { StorageModule } from '@ngx-builders/pwa-local-storage';
@NgModule({
imports: [
StorageModule.forRoot({
IDBNoWrap: false, // Here
})
]
})
export class AppModule {}
If you see this configuration (IDBNoWrap
set to false
),
unfortunately you can't manage interoperability,
and you can't change the configuration either if your app is already in production,
as it would mean the loss of all previously stored data.
When storing in indexedDB
, names are used for the database and the object store,
so you will need that all APIs use the same names.
- Option 1 (recommended): change this lib config, according to your other APIs:
import { StorageModule } from '@ngx-builders/pwa-local-storage';
@NgModule({
imports: [
StorageModule.forRoot({
IDBNoWrap: true, // Not required in versions >= 9
IDBDBName: 'customDataBaseName',
IDBStoreName: 'customStoreName',
})
]
})
export class AppModule {}
- Option 2: keep the config of this lib and change the options in the other APIs, by using the values exported by the lib:
if (this.storage.backingEngine === 'indexedDB') {
const { database, store, version } = this.storage.backingStore;
}
This second option can be difficult to manage due to some browsers issues in some special contexts
(Firefox private mode and Safari cross-origin iframes),
as the information may be wrong at initialization,
as the storage could fallback from indexedDB
to localStorage
only after a first read or write operation.
In some cases (see the browser support guide),
indexedDB
is not available, and libs fallback to localStorage
.
Some libs prefixes localStorage
keys. This lib doesn't by default,
but you can add a prefix.
- Option 1 (recommended):
import { StorageModule } from '@ngx-builders/pwa-local-storage';
@NgModule({
imports: [
StorageModule.forRoot({
IDBNoWrap: true, // Not required in versions >= 9
LSPrefix: 'myapp_',
})
]
})
export class AppModule {}
- Option 2:
if (this.storage.backingEngine === 'localStorage') {
const { prefix } = this.storage.fallbackBackingStore;
}
Interoperability with localforage
lib can be achieved with this config:
import { StorageModule } from '@ngx-builders/pwa-local-storage';
@NgModule({
imports: [
StorageModule.forRoot({
IDBNoWrap: true, // Not required in versions >= 9
LSPrefix: 'localforage/',
IDBDBName: 'localforage',
IDBStoreName: 'keyvaluepairs',
})
]
})
export class AppModule {}
Interoperability with native indexedDB
can be achieved that way:
if (this.storage.backingEngine === 'indexedDB') {
const { database, store, version } = this.storage.backingStore;
const dbRequest = indexedDB.open(database, version);
dbRequest.addEventListener('success', () => {
const store = dbRequest.result.transaction([store], 'readonly').objectStore(store);
const readRequest = store.get('someindex');
});
}
In indexedDB
, creating a store is only possible inside the upgradeneeded
event,
which only happens when opening the database for the first time,
or when the version change (but this case doesn't happen in this lib).
If this step is missing, then all indexedDB
operations in the lib will fail as the store will be missing.
Then, you need to ensure:
- you use the same database
version
as the lib (default to1
), - the store is created:
- by letting this lib to be initialized first (beware of concurrency issues),
- or if another API is going first, it needs to take care of the creation of the store (with the same name).
Most librairies (like this one and localforage
) will prevent you to store undefined
,
due to technical issues in the native APIs.
But if you use the native APIs (localStorage
and indexedDB
) directly,
you could manage to store undefined
, but it will then throw exceptions in some cases.
So don't store undefined
.
This lib only allows string
keys, while indexedDB
allows some other key types.
So if you use this lib keys()
method, all keys will be converted to a string
.