I am having issues with my SQLiteMock provider not getting picked up. What am I doing wrong. My understanding is that when I use "{ provide: SQLite, useClass: SQLiteMock }", that the SQLiteMock class should be used instead of SQLite. However, I am not experiencing that unless I specifically go in to Techdao.ts and explicitly say to use SQLiteMock and then pass that in instead of SQLite. What am I missing or doing wrong?
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));
}
}
You are almost there.
Adding the
{ provide: SQLite, useClass: SQLiteMock }
is not enough.You need to import and use your own
SQLiteMock
instead of the standard library.So if you had the following
Camera
mock:then in another .ts file wherein you would otherwise consume the
Camera
, you have to use your ownCameraMock
instead.When you are done with development of the feature, edit your code to switch back to using the actual
Camera
. You can even do clever tricks with environment variables to use different libs for dev and prod builds.