我正在尝试使用Dart中的sqljocky对数据库进行sql访问。由于我想用我的数据库处理程序返回的结果进行一些计算,该方法返回一个Future。
但是当我尝试运行它时,我收到以下错误:
Uncaught Error: The null object does not have a method 'then'`
我运行了调试器,发现此错误引发:
db.query('select * from user where email="$email"').then(...)
但是catchError子句不会触发。
我的处理程序方法是:
// db is a ConnectionPool
Future<Map<String,String>> queryUser(String email){
print(email);
db.query('select * from user where email="${email}"').then((result) { // here raise the error
Map<String,String> results = new Map<String,String>();
result.forEach((row){
results['status'] = '200';
results['ID'] = row[0];
results['Image'] = row[1];
results['Name'] = row[2];
results['Email'] = row[3];
results['Password'] = row[4];
});
return results;
}).catchError((error){
Map<String,String> results = new Map<String,String>();
results['status'] = '500';
return results;
});
}
调用此处理程序的方法是:
List getUser(String email) {
Future<Map<String,String>> result = dbhandler.queryUser(email);
result.then((Map<String,String> result) {
String statuscode = result['status'];
result.remove('status');
String json = JSON.encode(result);
List pair = new List();
pair.add(statuscode);
pair.add(json);
return pair;
});
如果我直接在phpmyadmin中运行查询,它会返回正确的数据,所以它是正确的。
有人可以给我一些关于如何解决它的提示吗?
答案 0 :(得分:1)
queryUser()方法将始终返回null,因为没有return语句。在Dart的下一个版本中,会有一个静态提示警告,但目前没有。
也许下面的代码就是你要做的。注意db.query()之前的初始return语句,以及额外的result.toList()调用。我没有测试过这个,所以可能有一两个错字。
Future<Map<String,String>> queryUser(String email){
print(email);
return db.query('select * from user where email="${email}"')
.then((result) => result.toList())
.then((rows) {
var row = rows.single;
Map<String,String> results = new Map<String,String>();
results['status'] = '200';
results['ID'] = row[0];
results['Image'] = row[1];
results['Name'] = row[2];
results['Email'] = row[3];
results['Password'] = row[4];
return results;
}).catchError((error){
Map<String,String> results = new Map<String,String>();
results['status'] = '500';
return results;
});
}
你也可以使用地图文字使这个有点可爱:
Future<Map<String,String>> queryUser(String email){
return db.query('select * from user where email="${email}"')
.then((result) => result.toList())
.then((rows) => <String, String> {
'status': '200',
'ID': rows.single[0],
'Image': rows.single[1],
'Name': rows.single[2],
'Email': rows.single[3],
'Password': rows.single[4] })
.catchError((error) => <String, String> {'status': '500'});
}
答案 1 :(得分:0)
最后我找到了使用 Completer 控制 Future 对象的答案,但真正的问题是,正如Greg Lowe所说,我的方法没有返回任何内容它们在 then 子句之前结束。
使用完成符号,我将查询方法设为:
Future<Map<String,String>> queryUser(String email){
Completer c = new Completer();
db.query('select * from user where email="$email"').then((result) {
Map<String,String> results = new Map<String,String>();
result.forEach((row){
results['status'] = '200';
results['ID'] = row[0].toString();
results['Image'] = row[1];
results['Name'] = row[2];
results['Email'] = row[3];
results['Password'] = row[4];
}).then((onValue){
c.complete(results);
});
}).catchError((error){
Map<String,String> results = new Map<String,String>();
results['status'] = '500';
c.completeError((e) => print("error en queryUser"));
});
return c.future;
}
我在使用 foreach 方法时也解决了一个错误,起初我认为它什么都没有返回,但在那之后,我注意到它返回了一个Future,所以我添加了一个then子句。
我的getUser方法:
Future<List> getUser(String email) {
Completer c = new Completer();
Future<Map<String,String>> result = dbhandler.queryUser(email);
result.then((Map<String,String> result) {
String statuscode = result['status'];
result.remove('status');
String json = JSON.encode(result);
List pair = new List();
pair.add(statuscode);
pair.add(json);
c.complete(pair);
});
return c.future;
}
在这些变化之后,一切正常