how to use lokijs-cordova-fs-adapter in ionic 2

两盒软妹~` 提交于 2019-12-06 11:34:44

问题


I am trying to use lokijs in my ionic 2 app. i am able to use lokijs.js. when trying to persist using adapter i am not able to. i ready lokijs-cordova-fs-adapter can be used. but when i refer it in my app as below: getting an error that its not able to locate.

var LokiCordovaFSAdapter = require("./cordova-file-system-adapter");

tried adding it in my index.html and tried creating adapter in my ts file as below:

var adapter = new LokiCordovaFSAdapter({"prefix": "loki"});

getting syntax error in this case. can someone give an example on how to use it?


回答1:


Ciao, this works on Ionic 2, so step-by-step (I did this inside a service):

  1. Check if both dependencies are installed:

    npm install lokijs --save
    npm install loki-cordova-fs-adapter --save
    
  2. Declare and import the following (before the class declaration):

    declare var require: any;
    var loki = require('lokijs');
    var LokiCordovaFSAdapter = require("loki-cordova-fs-adapter");
    var adapter = new LokiCordovaFSAdapter({"prefix": "loki"});
    
  3. Use the following inside the service class:

    db: any; // LokiJS database
    pandas: any; // our DB's document collection object
    
    constructor() {
      console.log("* inicializando...");
    
      this.db = new loki('pandas.db', {
        autoload: true,
        autoloadCallback: function() {
          console.log("* database loaded...")
        },
        autosave: true,
        autosaveInterval: 10 * 1000, //every 10 seconds
        adapter: adapter
      });
    }
    
  4. Use it (this code is also inside the service class):

    load() {
      let collection = this.db.getCollection('pandas');
      if (collection == null) {
        this.pandas = this.db.addCollection('pandas');
      } else {
        this.pandas = collection;
      }
    }
    
    pandaKamasutra() {
      console.log("* Save the pandas...");
      for (let i=0; i < 100; i++)
        this.pandas.insert({ name: 'Panda ' + (i+1), surename: "Whurgh " + i });
    }
    
    showPandas() {
      var results = this.pandas.find({});
      for (let r of results)
        console.log(`% id: ${r.$loki}, Panda: ${r.name}`);
    }
    

I spent this afternoon solving this, after swimming around both LokiJS and lokijs-cordova-fs-adapter code, I found the 'light' in the Ionic documentation here.

Hope it works for you too. =]




回答2:


See my post at https://github.com/cosmith/loki-cordova-fs-adapter/issues/15 for how to do this in Ionic2 (reposted here).

I finally have this running in an Ionic2 app (with typescript). Be sure to install the plugin cordova-plugin-file. Then use the adapter at the bottom like a normal Provider in Ionic2 (I have it installed in /src/lib/loki-cordova-fs-adapter in my project - named as index.ts).

For usage, here is an example:

import { Injectable } from '@angular/core'
import { Platform } from 'ionic-angular'
import * as Loki from 'lokijs'
import * as LokiIndexedAdapter from 'lokijs/src/loki-indexed-adapter'
import { LokiCordovaFSAdapter } from 'lib/loki-cordova-fs-adapter'

const DATABASE_NAME: string = 'yourFilename.db.json'

@Injectable()
export class DatabaseProvider {

  private lokiOptions: any = {
    verbose: true,
    autosave: true,
    autosaveInterval: 60000,
    autoload: true
  }
  private db: any

  public constructor (private platform: Platform, private mobileAdapter: LokiCordovaFSAdapter) {}

  public load (successCallback: any): void {
    if (this.db) {
      successCallback()
    } else {
      this.db = this.loadDatabase(DATABASE_NAME, successCallback)
    }
  }

  private loadDatabase (databaseName: string, successCallback: any): any {
    this.lokiOptions.autoloadCallback = successCallback
    if (this.platform.is('cordova')) {
      this.lokiOptions.adapter = this.mobileAdapter
    } else {
      this.lokiOptions.adapter = new LokiIndexedAdapter()
    }
    return new Loki(databaseName, this.lokiOptions)
  }
}

Here is the adapter:

import { Injectable } from '@angular/core'
class LokiCordovaFSAdapterError extends Error {}

// const TAG: string = '[LokiCordovaFSAdapter]'
declare var window: any
declare var cordova: any

@Injectable()
export class LokiCordovaFSAdapter {
  private options: any

  public constructor () {
    this.options = {'prefix': 'loki'}
  }

  public saveDatabase (dbname: string, dbstring: string, callback: any): any {
    // console.log(TAG, 'saving database')
    this._getFile(dbname,
      (fileEntry) => {
        fileEntry.createWriter(
          (fileWriter) => {
            fileWriter.onwriteend = () => {
              if (fileWriter.length === 0) {
                const blob: any = this._createBlob(dbstring, 'text/plain')
                fileWriter.write(blob)
                callback()
              }
            }
            fileWriter.truncate(0)

          },
          (err) => {
            // console.log(TAG, 'error writing file', err)
            throw new LokiCordovaFSAdapterError('Unable to write file' + JSON.stringify(err))
          }
        )
      },
      (err) => {
        // console.log(TAG, 'error getting file', err)
        throw new LokiCordovaFSAdapterError('Unable to get file' + JSON.stringify(err))
      }
    )
  }

  public loadDatabase (dbname: string, callback: any): void {
    // console.log(TAG, 'loading database')
    this._getFile(dbname,
      (fileEntry) => {
        // console.log('got database file')
        fileEntry.file((file) => {
          const reader: FileReader = new FileReader()
          reader.onloadend = (event: any) => {
            const contents: any = event.target.result
            if (contents.length === 0) {
              // console.log(TAG, 'database is empty')
              callback(null)
            } else {
              // console.log('sending back database')
              callback(contents)
            }
          }
          reader.readAsText(file)
        }, (err) => {
          // console.log(TAG, 'error reading file', err)
          callback(new LokiCordovaFSAdapterError('Unable to read file' + err.message))
        })
      },
      (err) => {
        // console.log(TAG, 'error getting file', err)
        callback(new LokiCordovaFSAdapterError('Unable to get file: ' + err.message))
      }
    )
  }

  public deleteDatabase (dbname: string, callback: any): void {
    window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
      (dir) => {
        const fileName: string = this.options.prefix + '__' + dbname
        dir.getFile(fileName, { create: true },
          (fileEntry) => {
            fileEntry.remove(
              () => {
                callback()
              },
              (err) => {
                // console.log(TAG, 'error delete file', err)
                throw new LokiCordovaFSAdapterError('Unable delete file' + JSON.stringify(err))
              }
            )
          },
          (err) => {
            // console.log(TAG, 'error delete database', err)
            throw new LokiCordovaFSAdapterError(
              'Unable delete database' + JSON.stringify(err)
            )
          }
        )
      },
      (err) => {
        throw new LokiCordovaFSAdapterError(
          'Unable to resolve local file system URL' + JSON.stringify(err)
        )
      }
    )
  }

  private _getFile (name: string, handleSuccess: any, handleError: any): void {
    // console.log(TAG, 'Retrieving file: ' + name)
    window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
      (dir) => {
        const fileName: string = this.options.prefix + '__' + name
        dir.getFile(fileName, { create: true }, handleSuccess, handleError)
      },
      (err) => {
        throw new LokiCordovaFSAdapterError(
          'Unable to resolve local file system URL' + JSON.stringify(err)
        )
      }
    )
  }

  // adapted from http://stackoverflow.com/questions/15293694/blob-constructor-browser-compatibility
  private _createBlob (data: string, datatype: string): any {
    let blob: any

    try {
      blob = new Blob([data], { type: datatype })
    } catch (err) {
      window.BlobBuilder = window.BlobBuilder ||
        window.WebKitBlobBuilder ||
        window.MozBlobBuilder ||
        window.MSBlobBuilder

      if (err.name === 'TypeError' && window.BlobBuilder) {
        const bb: MSBlobBuilder = new window.BlobBuilder()
        bb.append(data)
        blob = bb.getBlob(datatype)
      } else if (err.name === 'InvalidStateError') {
        // InvalidStateError (tested on FF13 WinXP)
        blob = new Blob([data], { type: datatype })
      } else {
        // We're screwed, blob constructor unsupported entirely
        throw new LokiCordovaFSAdapterError(
          'Unable to create blob' + JSON.stringify(err)
        )
      }
    }
    return blob
  }
}


来源:https://stackoverflow.com/questions/42386734/how-to-use-lokijs-cordova-fs-adapter-in-ionic-2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!