Hi!
I’d like to share my experience with persistence storage with ionic
Offline applications have to store a lot of (complex or not) objects.
Solution 1 : https://github.com/TheCocoaProject/cordova-plugin-nativestorage
But we can read in “When not to use the plugin” section : For storing many objects please consider trying a database-based strategy
Solution 2 : https://ionicframework.com/docs/storage/
Can be a solution but in my case I have to search data with complex parameters
Solution 3 : https://github.com/litehelpers/Cordova-sqlite-storage
Good solution but it’s a pity to write some old SQL queries instead of using the power of javascript such as NoSQL database.
Solution 4 : http://lokijs.org : LokiJS is an in-memory database with persistable NoSQL db for Cordova / Phonegap / Nativescript
OK, but how to make persistable data, which adapter to use?
I already use this library with ionic 1 and file adapter, but very documention exist for angular2+ that’s why I share my experience.
Which adapter to use : https://github.com/techfort/LokiJS/wiki/LokiJS-persistence-and-adapters
LokiIndexedAdapter is a good agreement. Available to store up to 60Mb an supported by major OS/browser version.
This is how I implement it with ionic3/Angular5
First add lokijs package in the app root directory
npm install lokijs --save
Import it and the indexDB adapter in a separated provider :
import 'rxjs/add/operator/toPromise';
import { Injectable } from '@angular/core';
import * as Loki from 'lokijs';
import * as LokiIndexedAdapter from 'lokijs/src/loki-indexed-adapter'
@Injectable()
export class Database {
db: any;
cat: any;
constructor() {
}
loadDB() {
let promise = new Promise((resolve, reject) => {
let adapter = new LokiIndexedAdapter();
this.db = new Loki('CAT.db', {
autosave: true,
//autoload: true,
autosaveInterval: 4 * 1000,
adapter: adapter
});
this.db.loadDatabase({}, (err) => {
if (err) {
}
else {
console.log("database loaded.");
this.cat = this.db.getCollection('CAT');
resolve();
}
});
});
return promise;
}
initDB() {
let promise = new Promise((resolve, reject) => {
let seq = this.api.get('initGame', param).share();
seq.subscribe((res: any) => {
let cat = this.db.getCollection('CAT');
if (cat) {
this.db.removeCollection('CAT');
}
this.cat = this.db.addCollection('CAT', { 'unique': 'i' });
this.cat.insert(res.items);
resolve(true);
}, err => {
console.error('ERROR', err);
});
});
return promise;
}
update(item) {
this.cat.update(item);
}
}
Then you easily call this provier from other pages/providers :
let loading = this.loadingCtrl.create({
content: 'Loading...'
});
loading.present();
this.database.initDB().then(() => {
loading.dismiss();
this.navCtrl.setRoot('WelcomePage', {}, {
animate: true,
direction: 'forward'
});
});
Hoping that this can be helpful