2

Dart でsqljockyを使用して、データベースへの SQL アクセスをコーディングしようとしています。データベース Handler から返された結果を使用して何らかの計算を行いたいので、メソッドは 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

return ステートメントがないため、queryUser() メソッドは常に null を返します。Dart の次のリリースでは、これに対する静的なヒントの警告が表示される予定ですが、現時点では何もありません。

おそらく、以下のコードはあなたが意図したものです。db.query() の前の最初の return ステートメントと、追加の result.toList() 呼び出しに注意してください。私はこれをテストしていないので、おそらくタイプミスが 1 つまたは 2 つあります。

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'});
}
于 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 に答える