NoSuchMethodError:方法“事务”在null上被调用。接收方:空Dart Flutter

时间:2018-08-18 21:51:05

标签: dart flutter

嗨,所以我试图在Flutter中制作一个应用程序,但是很难弄清楚出什么问题了。当您单击按钮时,我试图将其添加到sqflite数据库中,但是我尝试执行的任何操作似乎均不起作用。该值等于写的东西,但是然后我得到一个空错误。

这是一个页面,它将可以选择的硬币放入列表中。它可以工作,但是当您单击Listtile时,我试图添加它将名称添加到数据库。

import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:nodemarketcap/database.dart';
import 'package:sqflite/sqflite.dart';
class AddCoinPage extends StatefulWidget {
  final DatabaseClient databaseClient;

  AddCoinPage({Key key, @required this.databaseClient}) : super(key: key);
  @override
  _AddCoinPageState createState() => new _AddCoinPageState();
}



class _AddCoinPageState extends State<AddCoinPage> {
  TextEditingController controller = new TextEditingController();
  String coin;

   addCoin(coinname) async {
    setState(() {
      coin = coinname;
    });
    return widget.databaseClient.addCoin(coin);
  }
  // Get json result and convert it to model. Then add
  Future<Null> getUserDetails() async {
    final response = await http.get(url);
    final responseJson = json.decode(response.body);

    setState(() {
      _userDetails.clear();
      for (Map user in responseJson) {
        _userDetails.add(UserDetails.fromJson(user));
      }
    });
  }


  @override
  void initState() {
    super.initState();

    getUserDetails();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Add Coin'),
        backgroundColor: new Color(0xFF090909),
        elevation: 0.0,
      ),
      body: new Column(
        children: <Widget>[
          new Container(
            color: Colors.white,
            child: new Padding(
              padding: const EdgeInsets.all(8.0),
              child: new Card(
                child: new ListTile(
                  leading: new Icon(Icons.search),
                  title: new TextField(
                    controller: controller,
                    decoration: new InputDecoration(
                        hintText: 'Search', border: InputBorder.none),
                    onChanged: onSearchTextChanged,
                  ),
                  trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
                    controller.clear();
                    onSearchTextChanged('');
                  },),
                ),
              ),
            ),
          ),
          new Expanded(
            child: _searchResult.length != 0 || controller.text.isNotEmpty
                ? new ListView.builder(
              itemCount: _searchResult.length,
              itemBuilder: (context, i) {
                return new Card(
                  child: new ListTile(
                    title: new Text(_searchResult[i].name),
                      onTap: () {addCoin((_searchResult[i].name).toString());}
                  ),
                  margin: const EdgeInsets.all(0.0),
                );
              },
            )
                : new ListView.builder(
              itemCount: _userDetails.length,
              itemBuilder: (context, index) {
                return new Card(
                  child: new ListTile(
                    title: new Text(_userDetails[index].name),
                    onTap: () {addCoin(_userDetails[index].name);}
                  ),
                  margin: const EdgeInsets.all(0.0),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  onSearchTextChanged(String text) async {
    _searchResult.clear();
    if (text.isEmpty) {
      setState(() {});
      return;
    }

    _userDetails.forEach((userDetail) {
      if (userDetail.name.contains(text))
        _searchResult.add(userDetail);
    });

    setState(() {});
  }
}

List<UserDetails> _searchResult = [];

List<UserDetails> _userDetails = [];

final String url = 'https://nodemarketcap.com/api/api';
class UserDetails {
  final String name;

  UserDetails({this.name});

  factory UserDetails.fromJson(Map<String, dynamic> json) {
    return new UserDetails(
      name: json['name'],
    );
  }
}

这是数据库类文件夹。我只在其中使用头等舱。第二个尝试更多是失败的尝试,而不是我想做的事情,但是我保留了它,以防万一我需要重用某些东西。

import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';

class DatabaseClient  {
  Database database;

  Future create() async {
    Directory path = await getApplicationDocumentsDirectory();
    String dbPath = join(path.path, "database.db");

    database  = await openDatabase(dbPath, version: 1,
        onCreate: this._create);

  }
  Future _create(Database db, int version) async {
    await db.execute("""
            CREATE TABLE coins (
            id INTEGER PRIMARY KEY, 
            name VARCHAR(60) NOT NULL,
                  nameb VARCHAR(60) NOT NULL,
                  tickerCap VARCHAR(60) NOT NULL,                   
            roi DECIMAL(8, 2) NOT NULL,
            usdvalue DECIMAL(20, 6) NOT NULL,
            changep DECIMAL(6, 2) NOT NULL,
            mnCost BIGINT UNSIGNED NOT NULL,
            mncount BIGINT UNSIGNED  NOT NULL,          
            mnpriceusd DECIMAL(20, 2) NOT NULL,
            usdvol DECIMAL(30, 2) NOT NULL,
            dailyUSD DECIMAL(20, 4) NOT NULL,
            dailyBTC DECIMAL(20, 8) NOT NULL,
            monthlyUSD DECIMAL(20, 4) NOT NULL,
            monthlyBTC DECIMAL(20, 8) NOT NULL,
            yearlyUSD DECIMAL(20, 4) NOT NULL,
            yearlyBTC DECIMAL(20, 8) NOT NULL,  
            btcval DECIMAL(20, 8) NOT NULL, 
            usdMarketCap DECIMAL(20, 2) NOT NULL,   
            btcMarketCap DECIMAL(20, 2) NOT NULL,   
            btcvol DECIMAL(20, 8) NOT NULL
            )""");
  }
  addCoin (String name) async {
    await database.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT INTO coins(name, nameb, tickerCap, roi, usdvalue, changep, mnCost, mncount, mnpriceusd, usdvol, dailyUSD, dailyBTC, monthlyUSD, monthlyBTC, yearlyUSD, yearlyBTC, btcval, usdMarketCap, btcMarketCap, btcvol) VALUES(name, "refresh", "refresh", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)');
      print("insertedcoin: $id1");
    });
  }
  updateCoin (name, nameb, tickerCap, roi, usdvalue, changep, mnCost, mncount, mnpriceusd, usdvol, dailyUSD, dailyBTC, monthlyUSD, monthlyBTC, yearlyUSD, yearlyBTC, btcval, usdMarketCap, btcMarketCap, btcvol) async {
    int update = await database.rawUpdate(
        'UPDATE coins SET nameb = ?, tickerCap = ?, roi = ?, usdvalue = ?, changep = ?, mnCost = ?, mncount = ?, mnpriceusd = ?, usdvol = ?, dailyUSD = ?, dailyBTC = ?, monthlyUSD = ?, monthlyBTC = ?, yearlyUSD = ?, yearlyBTC = ?, btcval = ?, usdMarketCap = ?, btcMarketCap = ?, btcvol = ?  WHERE name = ?',
        [nameb, tickerCap, roi, usdvalue, changep, mnCost, mncount, mnpriceusd, usdvol, dailyUSD, dailyBTC, monthlyUSD, monthlyBTC, yearlyUSD, yearlyBTC, btcval, usdMarketCap, btcMarketCap, btcvol, name]);
    print("updated: $update");
  }
  getTest () async {
    List<Map> list = await database.rawQuery('SELECT * FROM coins');
    print(list);
  }
}

class Coins {
  Coins();

  int id;
  String name;
  String nameb;
  String tickerCap;
  double roi;
  double usdvalue;
  double changep;
  int mnCost;
  int mncount;
  double mnpriceusd;
  double usdvol;
  double dailyUSD;
  double dailyBTC;
  double monthlyUSD;
  double monthlyBTC;
  double yearlyUSD;
  double yearlyBTC;
  double btcval;
  double usdMarketCap;
  double btcMarketCap;
  double btcvol;

  static final columns = ["id", "name", "nameb", "tickerCap", "roi", "usdvalue", "changep", "mnCost", "mncount", "mnpriceusd", "usdvol", "dailyUSD", "dailyBTC", "monthlyUSD", "monthlyBTC", "yearlyUSD", "yearlyBTC", "btcval", "usdMarketCap", "btcMarketCap", "btcvol"];

  Map toMap() {
    Map map = {
      "name": name,
      "nameb": nameb,
      "tickerCap": tickerCap,
      "roi": roi,
      "usdvalue": usdvalue,
      "changep": changep,
      "mnCost": mnCost,
      "mncount": mncount,
      "mnpriceusd": mnpriceusd,
      "usdvol": usdvol,
      "dailyUSD": dailyUSD,
      "dailyBTC": dailyBTC,
      "monthlyUSD": monthlyUSD,
      "monthlyBTC": monthlyBTC,
      "yearlyUSD": yearlyUSD,
      "yearlyBTC": yearlyBTC,
      "btcval": btcval,
      "usdMarketCap": usdMarketCap,
      "btcMarketCap": btcMarketCap,
      "btcvol": btcvol
    };
    if (id != null) {
      map["id"] = id;
    }
    return map;
  }
  static fromMap(Map map) {
    Coins coins = new Coins();
    coins.id = map["id"];
    coins.name = map["name"];
    coins.nameb = map["nameb"];
    coins.tickerCap = map["tickerCap"];
    coins.roi = map["roi"];
    coins.usdvalue = map["usdvalue"];
    coins.changep = map["changep"];
    coins.mnCost = map["mnCost"];
    coins.mncount = map["mncount"];
    coins.mnpriceusd = map["mnpriceusd"];
    coins.usdvol = map["usdvol"];
    coins.dailyUSD = map["dailyUSD"];
    coins.dailyBTC = map["dailyBTC"];
    coins.monthlyUSD = map["monthlyUSD"];
    coins.yearlyUSD = map["yearlyUSD"];
    coins.yearlyBTC = map["yearlyBTC"];
    coins.btcval = map["btcval"];
    coins.usdMarketCap = map["usdMarketCap"];
    coins.btcMarketCap = map["btcMarketCap"];
    coins.btcvol = map["btcvol"];
    return coins;
  }
}

这是我得到的错误

08-18 15:06:20.845 19017-19136/com.nodemarketcap.nodemarketcap E/flutter: [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
    NoSuchMethodError: The method 'transaction' was called on null.
    Receiver: null
    Tried calling: transaction<Null>(Closure: (Transaction) => Future<Null>)
    #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:46:5)
    #1      DatabaseClient.addCoin (package:nodemarketcap/database.dart:46:20)
    <asynchronous suspension>
    #2      _AddCoinPageState.addCoin (package:nodemarketcap/add_coin_page.dart:26:34)
    <asynchronous suspension>
    #3      _AddCoinPageState.build.<anonymous closure>.<anonymous closure> (package:nodemarketcap/add_coin_page.dart:100:32)
    #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:494:14)
    #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:549:30)
    #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
    #7      TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:161:9)
    #8      TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:123:7)
    #9      GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
    #10     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:147:20)
    #11     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
    #12     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
    #13     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
    #14     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
    #15     _invoke1 (dart:ui/hooks.dart:134:13)
    #16     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:5)

所以我试图使它正常工作,但我却一头撞了。我可能在做一些愚蠢的事情,所以如果有人可以告诉我我做错了什么,并且可以告诉我我可以改进的地方。 :P IDK,谢谢。

1 个答案:

答案 0 :(得分:0)

错误 The method 'transaction' was called on null. 指出 transaction 在空方法上被调用。此问题的可能原因是 database 为 null。请务必初始化 database 以解决此问题。