我正在为 Ionic 应用程序使用离子原生 SQLite 数据库,并在使用 WebSQL 的浏览器中进行测试。在浏览器中一切正常,但在安卓设备中运行应用程序时。它给了我这样的错误Cannot read property 'transaction' of undefined
。下面是代码供参考。
1) DBProvider.ts
import { Platform } from 'ionic-angular';
import { Injectable } from '@angular/core';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
declare var window: any;
@Injectable()
export class DBProvider {
DB_NAME: string = 'DailySheet.db';
public websql = null;
public sqlite: SQLite;
sqliteobj: any;
public AppUsers = [];
constructor(public platform: Platform) {
if (this.platform.is('core')) {
this.websql = window.openDatabase(this.DB_NAME, "1.0", "Test DB", 2 * 1024 * 1024);
console.log('Database opened.');
this.createTable();
}
this.platform.ready().then(() => {
if (!this.platform.is('core')) {
this.sqlite.create({ name: this.DB_NAME, location: 'default' })
.then((db: SQLiteObject) => {
console.log('Database opened.');
this.sqliteobj = db;
this.createTable();
});
}
});
}
createTable() {
this.query(`CREATE TABLE IF NOT EXISTS AppUser (
UserId INTEGER NOT NULL,
MobileNo TEXT NOT NULL UNIQUE,
Email TEXT,
PRIMARY KEY(UserId)
)`)
.then(data => {
console.log('Table created.');
})
.catch(err => {
console.error('Unable to create initial storage tables', err.tx, err.err);
});
}
getAppUsers(): Promise<any> {
let query = 'SELECT * FROM AppUser';
return this.query(query)
.then(data => {
if (data.res.rows.length > 0) {
console.log('Rows found.');
return data.res.rows;
}
else {
console.log('No rows found.');
}
});
}
insertAppUser(): Promise<any> {
let id = 1;
let mobileno = '8905606191';
let email = 'niravparsana94@gmail.com';
return this.query('INSERT INTO AppUser (UserId, MobileNo, Email) VALUES (' + id + ' ,\"' + mobileno + '\" ,\"' + email + '\")')
.then(data => {
console.log('Insert success.');
return data;
})
.catch(err => {
console.error('Unable to insert', err.tx, err.err);
});
}
updateAppUser(UserId): Promise<any> {
let query = "UPDATE Todo SET Email=? WHERE UserId=?";
return this.query(query, ['niravparsana@outlook.com', UserId])
.then(data => {
console.log('AppUser Updated.');
return data;
})
.catch(err => {
console.error('Unable to update', err.tx, err.err);
});
}
deleteAppUser(UserId): Promise<any> {
let query = "DELETE FROM AppUser WHERE UserId=?";
return this.query(query, [UserId])
.then(data => {
return data;
})
.catch(err => {
console.error('Unable to delete', err.tx, err.err);
});
}
query(query: string, params: any[] = []): Promise<any> {
return new Promise((resolve, reject) => {
try {
if (this.platform.is('core')) {
this.websql.transaction((tx: any) => {
tx.executeSql(query, params,
(tx: any, res: any) => resolve({ tx: tx, res: res }),
(tx: any, err: any) => reject({ tx: tx, err: err }));
},
(err: any) => reject({ err: err }));
}
else {
this.sqliteobj.transaction((tx: any) => {
tx.executeSql(query, params,
(tx: any, res: any) => resolve({ tx: tx, res: res }),
(tx: any, err: any) => reject({ tx: tx, err: err }));
},
(err: any) => reject({ err: err }));
}
} catch (err) {
reject({ err: err });
}
});
}
}
2) home.ts
import { Component, OnInit } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { DBProvider } from '../../providers/DBProvider';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage implements OnInit {
AppUsers: Array<Object>;
constructor(public navCtrl: NavController, private platform: Platform, public db: DBProvider) {
}
ionViewDidLoad() {
this.deleteAppUser();
this.insertAppUser();
this.getAllAppUsers();
}
ngOnInit() {
}
public deleteAppUser() {
this.db.deleteAppUser(1)
.then(data => {
if (data.res.rowsAffected == 1) {
console.log('AppUser Deleted.');
}
else {
console.log('No AppUser Deleted.');
}
})
.catch(ex => {
console.log(ex);
});
}
public insertAppUser() {
this.db.insertAppUser()
.then(data => {
})
.catch(ex => {
console.log(ex);
});
}
public getAllAppUsers() {
this.db.getAppUsers()
.then(data => {
this.AppUsers = data;
})
.catch(ex => {
console.log(ex);
});
}
}
在调试时,我发现代码在浏览器和移动设备中以不同的顺序运行。
在浏览器中
- DBProvider 构造函数
- this.CreateTable() 函数(DBProvider.ts)
- this.deleteAppUser() 函数(home.ts)
- this.insertAppUser() 函数(home.ts)
- this.getAllAppUsers() 函数(home.ts)
在安卓设备中
- DBProvider 构造函数
- this.deleteAppUser() 函数(home.ts)
- this.insertAppUser() 函数(home.ts)
- this.getAllAppUsers() 函数(home.ts)
- this.CreateTable() 函数(DBProvider.ts)
正如你可以在 DBProvider 构造函数中分配 this.sqliteobj 。但是在调试时我发现 home.ts 的函数在 this.sqliteobj 被分配之前调用,这就是为什么它会给出一个错误Cannot read property 'transaction' of undefined
。但接下来的问题是为什么 home.ts 中的函数在 this.sqliteobj 被分配之前被调用?