2

我正在尝试在 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 中运行查询,它会返回正确的数据,所以它是正确的。

有人可以给我一个关于如何解决它的提示吗?

4

2 回答 2

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;
      });
}

你也可以使用 map 文字让它更可爱一点:

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'});
}
于 2014-02-26T21:07:14.430 回答
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; 
}

在这些更改之后,一切正常

于 2014-02-28T03:04:35.987 回答