I have followed the following tutorial (Ionic Native SQLite Storage — Browser Development and Testing Setup. | by Johanna altmann | Medium) in order to mock sqlite. My code is provided at GitHub - Yavari/ionic-sqlite-mock, The mock is not recognized and I am getting the error bellow. I am new to both ionic and angular so I would appreciate if someone could help me with this issue.
ERROR TypeError: Cannot read property ‘then’ of undefined
at Tab1Page.push…/src/app/tab1/tab1.page.ts.Tab1Page.ngOnInit (tab1.page.ts:19)
at checkAndUpdateDirectiveInline (core.js:22098)
at checkAndUpdateNodeInline (core.js:23362)
at checkAndUpdateNode (core.js:23324)
at debugCheckAndUpdateNode (core.js:23958)
at debugCheckDirectivesFn (core.js:23918)
at Object.eval [as updateDirectives] (Tab1Page_Host.ngfactory.js? [sm]:1)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23910)
at checkAndUpdateView (core.js:23306)
at callViewAction (core.js:23547)
The create method in SQLiteMock is not called so it is as if my provide in the app.module.ts is not working
//https://github.com/Yavari/ionic-sqlite-mock/blob/master/src/app/app.module.ts
import { SQLite } from '@ionic-native/sqlite';
import { SQLitePorter } from '@ionic-native/sqlite-porter';
import { SQLiteMock, SQLitePorterMock } from './mocks/sqlite.mock';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
{ provide: SQLite, useClass: SQLiteMock },
{ provide: SQLitePorter, useClass: SQLitePorterMock },
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
This is how I am trying to use it:
// https://github.com/Yavari/ionic-sqlite-mock/blob/master/src/app/tab1/tab1.page.ts
import { Component, OnInit } from '@angular/core';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page implements OnInit {
constructor(private sqlite: SQLite) {
}
ngOnInit(): void {
this.sqlite.create({
name: 'data.db',
location: 'default'
}).then((db: SQLiteObject) => {
db.executeSql('create table danceMoves(name VARCHAR(32))', [])
.then(() => console.log('Executed SQL'))
.catch(e => console.log(e));
}).catch(e => console.log(e));
}
}
This is my mock class that I have taken from the tutorial:
// https://github.com/Yavari/ionic-sqlite-mock/blob/master/src/app/mocks/sqlite.mock.ts
/*
Implemented with the help of https://www.techiediaries.com/mocking-native-sqlite-plugin/
*/
import { SQLiteDatabaseConfig } from '@ionic-native/sqlite';
//SQL file is loaded via script tag in index.html --> <script src="assets/sql/sql.js"></script>
declare var SQL;
export class SQLiteObject {
_objectInstance: any;
constructor(_objectInstance: any) {
this._objectInstance = _objectInstance;
};
executeSql(statement: string, params: any): Promise<any> {
return new Promise((resolve, reject) => {
try {
console.log(statement)
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);
}
});
};
sqlBatch(statements: string[], params: any): Promise<any> {
return new Promise((resolve, reject) => {
try {
var rows: Array<any> = [];
for (let statement of statements) {
console.log(statement)
var st = this._objectInstance.prepare(statement, params);
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(),
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);
}
});
};
}
/*
Implemented using edited code from actual cordova plugin
*/
export class SQLitePorterMock {
/**
* Trims leading and trailing whitespace from a string
* @param {string} str - untrimmed string
* @returns {string} trimmed string
*/
trimWhitespace(str) {
return str.replace(/^\s+/, "").replace(/\s+$/, "");
}
importSqlToDb(db, sql, opts = {}) {
try {
const statementRegEx = /(?!\s|;|$)(?:[^;"']*(?:"(?:\\.|[^\\"])*"|'(?:\\.|[^\\'])*')?)*/g;
var statements = sql
.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, "") // strip out comments
.match(statementRegEx);
if (statements === null || (Array.isArray && !Array.isArray(statements))) statements = [];
// Strip empty statements
for (var i = 0; i < statements.length; i++) {
if (!statements[i]) {
delete statements[i];
}
}
return db.sqlBatch(statements)
} catch (e) {
console.error(e.message);
}
}
}
export class SQLiteMock {
public create(config: SQLiteDatabaseConfig): Promise<SQLiteObject> {
console.log("creating");
var db;
var storeddb = localStorage.getItem("database");
if (storeddb) {
var arr = storeddb.split(',');
db = new SQL.Database(arr);
}
else {
db = new SQL.Database();
}
return new Promise((resolve, reject) => {
resolve(new SQLiteObject(db));
});
}
}