我正在处理带有sqlite存储空间的Ionic 2(2.0.0-rc.2
)应用,并且我遇到了一些问题,因此我在这里寻求帮助。
首次启动应用程序时,我要创建数据库(表格),插入一些值。到目前为止一切顺利。但是,当我尝试检索数据并从数据库中读取数据时,我收到了错误。
上课时我正在谈论:
import {Component} from '@angular/core';
import {Platform} from 'ionic-angular';
import {StatusBar, Splashscreen, SQLite} from 'ionic-native';
import {HomePage} from '../pages/home/home';
@Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
users = [];
rootPage = HomePage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
let db = new SQLite();
console.log("open database app.compontent")
db.openDatabase({
name: "data.db",
location: "default"
}).then(() => {
db.executeSql("CREATE TABLE IF NOT EXISTS user (iduser INTEGER PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT, castleType TEXT, castleHealth INTEGER); ", {}).then((data) => {
console.log("USER TABLE CREATED: ", data);
}, (error) => {
console.error("USER Unable to execute sql", error);
});
db.executeSql("CREATE TABLE IF NOT EXISTS melding (idmelding INTEGER PRIMARY KEY AUTOINCREMENT, meldingType TEXT, meldingTitel TEXT, meldingOmschrijving TEXT, ruimte INTEGER, user_iduser INTEGER, FOREIGN KEY (user_iduser) REFERENCES user(iduser)); ", {}).then((data) => {
console.log("MELDING TABLE CREATED: ", data);
}, (error) => {
console.error("MELDING Unable to execute sql", error);
});
db.executeSql("CREATE TABLE IF NOT EXISTS kasteelOnderdelen (idkasteelOnderdelen INTEGER PRIMARY KEY AUTOINCREMENT, onderdeelNaam TEXT, onderdeelShort TEXT, onderdeelHealth TEXT); ", {}).then((data) => {
console.log("KASTEELONDERDELEN TABLE CREATED: ", data);
}, (error) => {
console.error("KASTEELONDERDELEN Unable to execute sql", error);
});
db.executeSql("CREATE TABLE IF NOT EXISTS user_has_kasteelOnderdelen (id INTEGER PRIMARY KEY AUTOINCREMENT, user_iduser INTEGER, kasteelOnderdelen_idkasteelOnderdelen INTEGER, FOREIGN KEY (user_iduser) REFERENCES user(iduser), FOREIGN KEY (kasteelOnderdelen_idkasteelOnderdelen) REFERENCES kasteelOnderdelen(idkasteelOnderdelen));", {}).then((data) => {
console.log("USER_HAS_KASTEELONDERDELEN TABLES CREATED: ", data);
}, (error) => {
console.error("USER_HAS_KASTEELONDERDELEN Unable to execute sql", error);
});
console.log('Creating database complete!');
db.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Jan', 'Klaassen', 'mannelijk', '10']).then((data) => {
console.log("Inserted row 1: ", data);
}, (error) => {
console.error("Unable to insert row 1: ", error);
});
db.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Klaas', 'Janssen', 'mannelijk', '5']).then((data) => {
console.log("Inserted row 2: ", data);
}, (error) => {
console.error("Unable to insert row 2: ", error);
});
db.executeSql('SELECT * FROM user', []).then((resultSet) => {
if(resultSet.res.rows.length > 0) {
this.users = [];
for(let i = 0; i < resultSet.res.rows.length; i++) {
this.users.push({
"iduser": resultSet.res.rows.item(i).iduser,
"firstname": resultSet.res.rows.item(i).firstname,
"lastname": resultSet.res.rows.item(i).lastname,
});
}
}
}, (error) => {
console.log(error);
});
}, (error) => {
console.error("Unable to open database", error);
});
Splashscreen.hide();
});
}
}
错误(当我在设备上运行它时(Nexus 5):
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 12 : Error: Uncaught (in promise): TypeError: Cannot read property 'rows' of undefined
at s (file:///android_asset/www/build/polyfills.js:3:8568)
at file:///android_asset/www/build/polyfills.js:3:8940
at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:14051)
at Object.inner.inner.fork.onInvokeTask (file:///android_asset/www/build/main.js:3:22982)
at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:13987)
at e.runTask (file:///android_asset/www/build/polyfills.js:3:11411)
at i (file:///android_asset/www/build/polyfills.js:3:8028)
at u (file:///android_asset/www/build/polyfills.js:2:16275)
at file:///android_asset/www/build/polyfills.js:2:16399
at MutationObserver.r (file:///android_asset/www/build/polyfills.js:2:14841)
其他调查结果/说明:
如果我写console.log(resultSet);
返回值为[object object]
现在它们都在同一个类中,而在longrun中它将在它自己的StorageProvider / Service中,但是我已经把它全部移到这里来调试它。 (到目前为止没有成功)
有人知道导致错误的原因吗?
提前致谢。
Poerkie
更新20-12(实施提示和建议后):
当前代码:
import {Injectable} from '@angular/core';
import 'rxjs/add/operator/map';
import {SQLite} from 'ionic-native';
import {Platform} from 'ionic-angular';
@Injectable()
export class StorageService {
public database: SQLite;
public users;
constructor(private platform: Platform) {
console.log(' StorageService Initialised');
this.platform.ready().then(() => {
this.database = new SQLite();
this.database.openDatabase({name: "data.db", location: "default"}).then(() => {
console.log("SUCCES Opening DB storageService");
let s1 = this.createUserTable()
let s2 = this.database.executeSql("CREATE TABLE IF NOT EXISTS melding (idmelding INTEGER PRIMARY KEY AUTOINCREMENT, meldingType TEXT, meldingTitel TEXT, meldingOmschrijving TEXT, ruimte INTEGER, user_iduser INTEGER, FOREIGN KEY (user_iduser) REFERENCES user(iduser)); ", {});
return Promise.all([s1, s2]).then(() => {
console.log('creating database complete!');
let i1 = this.insertUser();
let i2 = this.database.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Klaas', 'Janssen', 'mannelijk', '5']);
return Promise.all([i1, i2]).then((res) => {
console.log('all insert querys executed', res);
}).then(() => {
console.log('executing sql statement');
return this.database.executeSql('SELECT * FROM user', []);
}).then((resultSet) => {
console.log('after then((resultset): ' + resultSet);
console.log(JSON.stringify(resultSet, undefined, 2));
if (resultSet.res.rows.length > 0) {
console.log('if statement true');
this.users = [];
for (let i = 0; i < resultSet.res.rows.length; i++) {
console.log('forloop');
this.users.push({
"iduser": resultSet.res.rows.item(i).iduser,
"firstname": resultSet.res.rows.item(i).firstname,
"lastname": resultSet.res.rows.item(i).lastname,
});
}
console.log('after forloop');
}
}).catch((error) => {
console.error("db error", error);
})
})
}, (error) => {
console.log("ERROR oepening DB storageService: ", error);
});
});
}
public createUserTable() {
this.database.executeSql("CREATE TABLE IF NOT EXISTS user (iduser INTEGER PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT, castleType TEXT, castleHealth INTEGER); ", {}).then((data) => {
console.log("USER TABLE CREATED: ", data);
}, (error) => {
console.error("USER Unable to execute sql", error);
});
}
public insertUser() {
this.database.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Jan', 'Klaassen', 'mannelijk', '10']).then((data) => {
console.log('Insert Succesful');
}, (error) => {
console.error('user not inserted: ' + error);
});
}
}
nexus 5 outputlog:
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : StorageService Initialised
I/chromium: [INFO:CONSOLE(6)] " StorageService Initialised", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : CastleService initialized
I/chromium: [INFO:CONSOLE(6)] "CastleService initialized", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 5 : SlimLabsService initialized
I/chromium: [INFO:CONSOLE(5)] "SlimLabsService initialized", source: file:///android_asset/www/build/main.js (5)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 5 : Logging in!
I/chromium: [INFO:CONSOLE(5)] "Logging in!", source: file:///android_asset/www/build/main.js (5)
12-20 07:48:04.042 796-18483/? W/InputMethodManagerService: Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@fd827af attribute=null, token = android.os.BinderProxy@7d616de
D/CordovaWebViewImpl: onPageFinished(file:///android_asset/www/index.html)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 19 : DEVICE READY FIRED AFTER
I/chromium: [INFO:CONSOLE(19)] "DEVICE READY FIRED AFTER", source: file:///android_asset/www/build/main.js (19)
I/App: WARNING: Back Button Default Behavior will be overridden. The backbutton event will be fired!
D/SystemWebChromeClient: file:///android_asset/www/plugins/cordova-sqlite-storage/www/SQLitePlugin.js: Line 175 : OPEN database: data.db
I/chromium: [INFO:CONSOLE(175)] "OPEN database: data.db", source: file:///android_asset/www/plugins/cordova-sqlite-storage/www/SQLitePlugin.js (175)
V/SQLitePlugin: Android db implementation: built-in android.database.sqlite package
V/info: Open sqlite db: /data/user/0/com.ionicframework.cwistlev1105374/databases/data.db
D/SystemWebChromeClient: file:///android_asset/www/plugins/cordova-sqlite-storage/www/SQLitePlugin.js: Line 179 : OPEN database: data.db - OK
I/chromium: [INFO:CONSOLE(179)] "OPEN database: data.db - OK", source: file:///android_asset/www/plugins/cordova-sqlite-storage/www/SQLitePlugin.js (179)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : SUCCES Opening DB storageService
I/chromium: [INFO:CONSOLE(6)] "SUCCES Opening DB storageService", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : USER TABLE CREATED:
I/chromium: [INFO:CONSOLE(6)] "USER TABLE CREATED: ", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : creating database complete!
I/chromium: [INFO:CONSOLE(6)] "creating database complete!", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : Insert Succesful
I/chromium: [INFO:CONSOLE(6)] "Insert Succesful", source: file:///android_asset/www/build/main.js (6)
12-20 07:48:04.629 1596-1596/? I/Keyboard.Facilitator: onFinishInput()
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : all insert querys executed
I/chromium: [INFO:CONSOLE(6)] "all insert querys executed", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : executing sql statement
I/chromium: [INFO:CONSOLE(6)] "executing sql statement", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : after then((resultset): [object Object]
I/chromium: [INFO:CONSOLE(6)] "after then((resultset): [object Object]", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : {
"rows": {
"length": 42
},
"rowsAffected": 0
}
I/chromium: [INFO:CONSOLE(6)] "{
"rows": {
"length": 42
},
"rowsAffected": 0
}", source: file:///android_asset/www/build/main.js (6)
D/SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 6 : db error
I/chromium: [INFO:CONSOLE(6)] "db error", source: file:///android_asset/www/build/main.js (6)
其他信息: 没有关于错误的更多信息,或者我不知道如何检索错误。 (没有得到堆栈跟踪或任何东西); 为什么它不想传递结果!进入用户[]?
答案 0 :(得分:2)
您正在使用的db相关函数返回一个promise。 then()是异步的,意味着create,insert,select中的所有db函数都可以在调用then方法中的一个或多个之前执行。
假设您只有用户表,则需要
db.executeSql(`
CREATE TABLE IF NOT EXISTS user (
iduser INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT,
lastname TEXT,
castleType TEXT,
castleHealth INTEGER
); `, {})
.then((data) => {
console.log("USER TABLE CREATED: ", data);
db.executeSql(`
INSERT INTO user (
firstname,
lastname,
castletype,
castleHealth
) VALUES (?, ?, ?, ?)`,
['Jan', 'Klaassen', 'mannelijk', '10'])
.then((data) => {
//select here
console.log("Inserted row 1: ", data);
}, (error) => {
console.error("Unable to insert row 1: ", error);
});
}, (error) => {
console.error("USER Unable to execute sql", error);
});
等等。
您的resultset.res可能为null,因为您的表尚未创建。
同样打印对象:console.log(JSON.stringify(resultSet,undefined,2));
答案 1 :(得分:2)
我同意Suraj Rao关于异步结果的看法。我想补充一点,你可以在Promise.all()中完成所有创建表。当介于&#39;之间&#39;声明,放置&#39;返回&#39;在查询结果预期在下一个&#34;然后&#34;。例如:
query.then( (res) => { return query2 }
).then( (res2) => { do something }
).catch( (err) => {...});
在你的情况下:
let db = new SQLite();
console.log("open database app.compontent")
db.openDatabase({
name: "data.db",
location: "default"
}).then(() => {
let s1 = db.executeSql("CREATE TABLE IF NOT EXISTS user (iduser INTEGER PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT, castleType TEXT, castleHealth INTEGER); ", {});
let s2 = db.executeSql("CREATE TABLE IF NOT EXISTS melding (idmelding INTEGER PRIMARY KEY AUTOINCREMENT, meldingType TEXT, meldingTitel TEXT, meldingOmschrijving TEXT, ruimte INTEGER, user_iduser INTEGER, FOREIGN KEY (user_iduser) REFERENCES user(iduser)); ", {})
let sN = db.executeSql("CREATE TABLE ....);
return Promise.all([s1,s2,....,sN]);
).then(
() => {
console.log('Creating database complete!');
let i1 = db.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Jan', 'Klaassen', 'mannelijk', '10']);
let i2 = db.executeSql("INSERT INTO user (firstname, lastname, castletype, castleHealth) VALUES (?, ?, ?, ?)", ['Klaas', 'Janssen', 'mannelijk', '5']);
let iN = db.executeSql("INSERT INTO ....");
return Promise.all([i1,i2,....,iN]);
).then(
(res) => {
console.log('all insert over ' , res)
}
).then(
() => {return db.executeSql('SELECT * FROM user', []);}
).then(
(resultSet) => {
if(resultSet.res.rows.length > 0) {
this.users = [];
for(let i = 0; i < resultSet.res.rows.length; i++) {
this.users.push({
"iduser": resultSet.res.rows.item(i).iduser,
"firstname": resultSet.res.rows.item(i).firstname,
"lastname": resultSet.res.rows.item(i).lastname,
});
}
}
}
).catch(
(error) => {
console.error("db error", error);
}
);
答案 2 :(得分:1)
希望它对你有用,请参考下面的简单实现。
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
@Component({
selector: 'page-about',
templateUrl: 'about.html',
providers:[SQLite]
})
export class AboutPage {
rows: any;
data: any;
public people: Array<Object>;
getdata: string;
constructor(public navCtrl: NavController, private sqlite: SQLite) {
this.sqlite.create({
name: 'data.db',
location: 'default'
}).then((db: SQLiteObject) => {
db.executeSql('CREATE TABLE IF NOT EXISTS supriya(name VARCHAR(32))', {})
.then(() => console.log('Executed SQL'))
.catch(e => console.log(e));
db.executeSql('INSERT INTO supriya VALUES (?)', ['Supriya']).then(() => console.log('value inserted in SQL'))
.catch(e => console.log(e));
db.executeSql('select * from supriya', []).then(data => {
console.log("select statment executed"+ data);
this.people = [];
if(data.rows.length > 0) {
for(var i = 0; i < data.rows.length; i++) {
this.people.push({name: data.rows.item(i).name});
console.log(data.rows.item(i).name);
}
}
}, (error) => {
console.log("ERROR: " + JSON.stringify(error));
})
})
}
}
<ion-list>
<ion-item *ngFor="let person of people">
{{person.name}}
</ion-item>
</ion-list>