SQLite Mocking does not work in ionic

I am having problems with my SQLiteMock provider not receiving. What am I doing wrong. I understand that when I use {provide: SQLite, useClass: SQLiteMock} "the SQLiteMock class should be used instead of SQLite. However, I do not experience this unless I specifically go to Techdao.ts and explicitly say to use SQLiteMock and then pass that instead of SQLite What am I missing or something amiss?

I am using Ionic 3.

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { SQLite, SQLiteDatabaseConfig } from '@ionic-native/sqlite';
import { MyApp } from './app.component';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { Page1 } from '../pages/page1/page1';

declare var SQL;
class SQLiteMock {
    public create(config: SQLiteDatabaseConfig): Promise<SQLiteObject> {
        console.log("Create Mock SQLite Database.");
        var db = new SQL.Database();
        return new Promise((resolve, reject) => {
            resolve(new SQLiteObject(db));
        });
    }
}

class SQLiteObject {
    _objectInstance: any;
    constructor(_objectInstance: any) {
        this._objectInstance = _objectInstance;
    };
    public create(config: SQLiteDatabaseConfig): Promise<SQLiteObject> {
        var db;

        console.log("Open Mock SQLite Database.");
        var storeddb = localStorage.getItem("database");

        var arr = storeddb.split(',');
        if (storeddb) {
            db = new SQL.Database(arr);
        }
        else {
            db = new SQL.Database();
        }

        return new Promise((resolve, reject) => {
            resolve(new SQLiteObject(db));
        });
    }
    executeSql(statement: string, params: any): Promise<any> {
        console.log("Mock SQLite executeSql: " + statement);

        return new Promise((resolve, reject) => {
            try {
                var st = this._objectInstance.prepare(statement, params);
                var rows: Array<any> = [];
                while (st.step()) {
                    var row = st.getAsObject();
                    rows.push(row);
                }
                var payload = {
                    rows: {
                        item: function (i) {
                            return rows[i];
                        },
                        length: rows.length
                    },
                    rowsAffected: this._objectInstance.getRowsModified() || 0,
                    insertId: this._objectInstance.insertId || void 0
                };

                //save database after each sql query 
                var arr: ArrayBuffer = this._objectInstance.export();
                localStorage.setItem("database", String(arr));
                resolve(payload);
            } catch (e) {
                reject(e);
            }
        });
    };
}

@NgModule({
  declarations: [
    MyApp,
    Page1
  ],
  imports: [
      BrowserModule,
      HttpModule,
      IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    Page1
  ],
  providers: [
      StatusBar,
      Splashscreen,
      { provide: SQLite, useClass: SQLiteMock },
      { provide: ErrorHandler, useClass: IonicErrorHandler }
  ]
})
export class AppModule { }`

      

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any = Page1;

  public sqlstorage: SQLite;
  techdao: TechDAO;

  pages: Array<{title: string, component: any}>;

  constructor(public platform: Platform) {
      console.log("Platforms: " + platform.platforms());
      this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();

      this.initializeSQLite();

      Splashscreen.hide();

    });
  }

  initializeSQLite() {
      this.sqlstorage = new SQLite();
      this.techdao = new TechDAO(this.sqlstorage);

      this.techdao.createTables(); 
  }

  openPage(page) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }  
}

      

techdao.ts

import { SQLite, SQLiteDatabaseConfig, SQLiteObject } from '@ionic-native/sqlite';

export class TechDAO {
    sqlite: any;
    db: SQLiteObject;

    constructor(private _sqlite: SQLite) {
        this.sqlite = _sqlite;
    };

    public createTables() {
        this.sqlite.create({
            name: 'tech.db',
            location: 'default'
        }).then((_db: SQLiteObject) => {
            console.log("Create Database tables if they don't exist.");
            this.db = _db;

            this.createAppointmentTable();
        }).catch(e => console.log(e));  
    }

    createAppointmentTable() {
        this.db.executeSql(
            'create table if not exists appointment(' +
            'ticketnumber TEXT PRIMARY KEY,' +
            'customername TEXT,' +
            'contactemail TEXT,' +
            'contactphone TEXT' +
            ')', {})
            .then(() => console.log('Executed SQL - Create Appointment Table'))
            .catch(e => console.log(e));
    }    
}

      

+3


source to share


1 answer


You're almost there.

Adding is { provide: SQLite, useClass: SQLiteMock }

not enough.

You need to import and use your own SQLiteMock

instead of the standard library.

So, if you had the following Camera

mock:



import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

import { Camera } from '@ionic-native/camera';

class CameraMock extends Camera {
  getPicture(options) {
    return new Promise((resolve, reject) => {
      resolve("BASE_64_ENCODED_DATA_GOES_HERE");
    })
  }
}

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    { provide: Camera, useClass: CameraMock }
  ]
})
export class AppModule {}

      

then in another .ts file where you otherwise consume Camera

, you should use your own instead CameraMock

.

import { CameraMock } from "../mocks/camera-mock";

      

When you're done developing this feature, edit your code to revert to using the actual one Camera

. You can even do clever tricks with environment variables to use different libraries for dev and prod.

+1


source







All Articles