Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ionic 2 Error 'ReferenceError: sqlitePlugin is not defined'

I'm been using the ionic 2 native sqlite plugin to make a basic app to capture and store images to the phones local storage. I keep getting an uncaught exception error (seemingly from the sql plugin) sometimes when i run the app on the genymotion emulator.

This normally happens when the app reloads when i'm using the -live parameter(ionic run android -c -l). I also noticed that data which stored on the app doesn't appear(this again indicates that there is some problem loading the stored data when 'live reloading') I've put the error i get on the console below:

The Console error message

[13:28:27] Starting 'html'...
[13:28:27] Finished 'html' after 42 ms
HTML changed: www/build/pages/home/home.html
HTML changed: www/build/pages/map-detail-component/map-detail-component.html
HTML changed: www/build/pages/map-page/map-page.html
0     298305   log      Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
1     298474   group    EXCEPTION: Error: Uncaught (in promise): ReferenceError: sqlitePlugin is not defined
2     298475   error    EXCEPTION: Error: Uncaught (in promise): ReferenceError: sqlitePlugin is not defined
3     298476   error    STACKTRACE:
4     298477   error    Error: Uncaught (in promise): ReferenceError: sqlitePlugin is not defined
    at resolvePromise (http://192.168.56.1:8100/build/js/zone.js:418:31)
    at resolvePromise (http://192.168.56.1:8100/build/js/zone.js:403:17)
    at http://192.168.56.1:8100/build/js/zone.js:451:17
    at ZoneDelegate.invokeTask (http://192.168.56.1:8100/build/js/zone.js:225:37)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (http://192.168.56.1:8100/build/js/app.bundle.js:37360:41)
    at ZoneDelegate.invokeTask (http://192.168.56.1:8100/build/js/zone.js:224:42)
    at Zone.runTask (http://192.168.56.1:8100/build/js/zone.js:125:47)
    at drainMicroTaskQueue (http://192.168.56.1:8100/build/js/zone.js:357:35)
    at XMLHttpRequest.ZoneTask.invoke (http://192.168.56.1:8100/build/js/zone.js:297:25)
5     298478   groupEnd 
6     298481   error    Unhandled Promise rejection:, sqlitePlugin is not defined, ; Zone:, angular, ; Task:, Promise.then, ; Value:, [object Object], ReferenceError: sqlitePlugin is not defined
    at http://192.168.56.1:8100/build/js/app.bundle.js:97420:13
    at new ZoneAwarePromise (http://192.168.56.1:8100/build/js/zone.js:467:29)
    at SQLite.openDatabase (http://192.168.56.1:8100/build/js/app.bundle.js:97419:16)
    at new SqlService (http://192.168.56.1:8100/build/js/app.bundle.js:218:21)
    at DebugAppView.Object.defineProperty.get (MyApp.template.js:18:67)
    at DebugAppView._View_MyApp_Host0.injectorGetInternal (MyApp.template.js:35:79)
    at DebugAppView.AppView.injectorGet (http://192.168.56.1:8100/build/js/app.bundle.js:31753:21)
    at DebugAppView.injectorGet (http://192.168.56.1:8100/build/js/app.bundle.js:31945:49)
    at ElementInjector.get (http://192.168.56.1:8100/build/js/app.bundle.js:31246:33)
    at ElementInjector.get (http://192.168.56.1:8100/build/js/app.bundle.js:31249:48)
7     298519   log      DEVICE READY FIRED AFTER, 1004, ms
8     298609   log      Entering: map-page
9     298620   log      ERROR: , {}

This goes away when i restart the emulator but then sometimes appears again after more usage.

I thought this could be due to the SQLite db being created before the plugin is imported but i've imported the plugin in my root app.ts file (shown below) (the whole app can be seen in this github repo)

Root app.ts

@Component({
    template: '<ion-nav [root]="rootPage"></ion-nav>',
    // Declare services
    providers: [ SqlService ]
})
export class MyApp {
    rootPage: any = MapPage;

    constructor(platform: Platform) {
        platform.ready().then(() => {
            StatusBar.styleDefault();
        });
    }
}    
ionicBootstrap(MyApp);

I've confined any use of the plugin to an sqlService (shown below)

SQL Service

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { SQLite} from 'ionic-native';

@Injectable()
export class SqlService {
  private db: SQLite;
  private isOpen: boolean;

  public constructor() {
    if(!this.isOpen){
      this.db = new SQLite();
      this.db.openDatabase({
        name: "data.db",
        location: "default"
      }).then(() => {
        this.db.executeSql("CREATE TABLE IF NOT EXISTS places (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, img TEXT)", []).then((data) => {
          console.log("TABLE CREATED: " + data);
        }, (error) => {
          console.log("Unable to execute SQL" + error);
        });
        this.isOpen=true;
      });
    }
  }

  public add(title: string, base64Img: string) {
    return new Promise((resolve, reject) => {
      this.db.executeSql("INSERT INTO places (title, img) VALUES ( '"+ title +"', '"+ base64Img +"')", [])
        .then((data) => {
          resolve(data);
        }, (error) => {
          reject(error);
        });
    });
  }

  // Remove individual Location
  public remove(id: number){
    return new Promise((resolve, reject) => {
      this.db.executeSql("DELETE FROM places WHERE id = "+ id +";", [])
        .then((data) => {
          resolve(data);
        }, (error) => {
          reject(error);
        });
    });
  }

  public locDetail(id: number){
    return new Promise((resolve, reject) => {
      this.db.executeSql("SELECT * FROM places WHERE id = "+ id +";",[])
        .then((data) => {
          if(data.rows.length===1){
            // console.log("ttitle: " + data.rows.item(0).title + " id: " + data.rows.item(0).id + " img: " + data.rows.item(0).img );
            let place = [];
            place.push({
              id: data.rows.item(0).id,
              title: data.rows.item(0).title,
              img: data.rows.item(0).img
            });
            resolve(place);
          }
        }, (error) => {
          reject(error);
        });
    });
  }

  // Refresh and initialise the places object
  public refresh() {
    return new Promise((resolve, reject) => {
        this.db.executeSql("SELECT * FROM places", []).then((data) => {
          let place = [];
          if (data.rows.length > 0) {
            for (var i = 0; i < data.rows.length; i++) {
              place.push({ 
                id: data.rows.item(i).id,
                title: data.rows.item(i).title, 
                img: data.rows.item(i).img 
              });
            }
          }
          resolve(place);
        }, (error) => {
          reject(error);
        });
      }
    );
  }
}
like image 214
aheigins Avatar asked Nov 20 '22 18:11

aheigins


1 Answers

I recently had the same problem, make sure you check if the platform is ready also in your service. Import "Platform" from "ionic-angular" and execute your sqlite interaction code in the promise.then method.

like image 75
BeK Avatar answered Dec 09 '22 19:12

BeK