So i’m having a real hard time understanding how synchronous functions work in ionic2/angular.
Here is what i am trying to do. I am using the native sqlite library. When my function to request data from the database is called it has to be certain to open the database and that the 2 tables are created. I’ve created 1 function to do that
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
import 'rxjs/add/operator/map';
@Injectable()
export class ScanDatabaseProvider {
public database: SQLiteObject;
constructor(public http: Http, public sqlite: SQLite) {
this.openDatabase();
}
openDatabase(){
this.sqlite.create({
name: 'data.db',
location: 'default'
})
.then((db: SQLiteObject) => {
var sql = "CREATE TABLE IF NOT EXISTS `leads` ( `local_lead_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remote_lead_id` INTEGER, `uploaded` INTEGER DEFAULT 0, `name` TEXT, `email` TEXT, `age` INTEGER, `phone_number` TEXT, `address` TEXT )";
db.executeSql(sql, {})
.then(() => console.log('leads table created'))
.catch(e => console.log(e));
sql = "CREATE TABLE IF NOT EXISTS `scans` (`scan_id` INTEGER PRIMARY KEY AUTOINCREMENT,`lead_id` INTEGER,`measurement` INTEGER,`scan_date` TEXT,`scanner_id` INTEGER );";
db.executeSql(sql, {})
.then(() => console.log('scans table created'))
.catch(e => console.log(e));
this.database = db;
})
}
a second function also exists that calls the first before selecting the data out of the database
getHistory(lead_id){
this.openDatabase();
this.database.executeSql("SELECT * FROM scans", []).then((data) => {
console.log(JSON.stringify(data.rows));
return data;
}, (error) => {
console.log("ERROR: " + JSON.stringify(error));
})
}
The problem is that the opening of the openDatabase() function may not finish before getHistory() is called and in the process the database isn’t instantiated. So reading online introduces me to the idea of promises. So i figured i’d have a promise resolved in the openDatabase() function and then use “then” within my getHistory() function. My problem appears to be that openDatabase() can’t return a resolve since it has to wait for the sqlite call to finish. In other words a promise within a promise. here is the code i’ve tried which bombs because of one or two reasons.
openDatabase(): Promise<void>{
this.sqlite.create({
name: 'data.db',
location: 'default'
})
.then((db: SQLiteObject) => {
var sql = "CREATE TABLE IF NOT EXISTS `leads` ( `local_lead_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remote_lead_id` INTEGER, `uploaded` INTEGER DEFAULT 0, `name` TEXT, `email` TEXT, `age` INTEGER, `phone_number` TEXT, `address` TEXT )";
db.executeSql(sql, {})
.then(() => console.log('leads table created'))
.catch(e => console.log(e));
sql = "CREATE TABLE IF NOT EXISTS `scans` (`scan_id` INTEGER PRIMARY KEY AUTOINCREMENT,`lead_id` INTEGER,`measurement` INTEGER,`scan_date` TEXT,`scanner_id` INTEGER );";
db.executeSql(sql, {})
.then(() => console.log('scans table created'))
.catch(e => console.log(e));
this.database = db;
return Promise.resolve();
})
}
getHistory(lead_id){
this.openDatabase().then(() =>
this.database.executeSql("SELECT * FROM scans", []).then((data) => {
console.log(JSON.stringify(data.rows));
return data;
}, (error) => {
console.log("ERROR: " + JSON.stringify(error));
})
);
}
in order for this to work i have to return a resolve from with the main openDatabase() function and not in it’s child “then”. This obviously means it isn’t waiting for the child to finish. I know i’m probably explaining this poorly since i don’t really understand what is going on completely. Help me please. any explanations i find online all seem to go at this in different approaches so i’m really confused.
I should add that the error i get with the latest code in app is "Uncaught (in promise): TypeError: undefined not an object(evaluating ‘_this.database.executeSql’)
Which i gather is because the database object hasn’t been initialized yet.