sqljocky查询没有'then'方法(dart数据库访问)

时间:2014-02-26 19:51:59

标签: dart dart-async

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

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

2 个答案:

答案 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; 
}

在这些变化之后,一切正常