NoSuchMethodError: The method 'isBefore' was called on null

NoSuchMethodError: The method 'isBefore' was called on null

我尝试按日期过滤 JSON 数据。我坚持比较日期。输入是来自 GET 请求的列表,然后转换为要使用的实际数据类型(DateTime、String)。之后,我将选择一个日期范围,然后将它们与列表中某个对象的日期进行比较。不知道为什么总是报Null的错误。

class BudgetDateRangePicker extends StatefulWidget {
  final List<Transaction> transactions;
  BudgetDateRangePicker({Key key, this.transactions}) : super(key: key);
  @override
  State<StatefulWidget> createState() => _BudgetDateRangePickerState();
}

class _BudgetDateRangePickerState extends State<BudgetDateRangePicker> {
  // DateTime _toDate = DateTime.now();
  // DateTime _fromDate = DateTime.now().subtract(Duration(days: 7));
  DateTime _toDate = DateTime.now();
  DateTime _fromDate = DateTime.now().subtract(Duration(days: 7));
  List<Transaction> trans = [];
  Future<void> _selectDate(BuildContext context) async {
    final List<DateTime> picked = await DateRangePicker.showDatePicker(
        context: context,
        initialLastDate: new DateTime.now(),
        initialFirstDate: (new  DateTime.now().subtract(Duration(days: 7))),
        firstDate: new DateTime(2015),
        lastDate: new DateTime(DateTime.now().year+1));
    if (picked != null && picked.length == 2) {
      setState(() {
        _fromDate = picked[0];
        _toDate = picked[1];
        //trans = widget.transactions.where((t)=>(t.date.millisecondsSinceEpoch >= picked[0].millisecondsSinceEpoch  ) && t.date.millisecondsSinceEpoch>=picked[1].millisecondsSinceEpoch).toList();
        for (var item in widget.transactions) {
          // var t = DateFormat('yyyy-MM-dd').parse(item.date);
          var t = item.date;
          if (t.isBefore(_toDate) &&
              t.isAfter(_fromDate)) {
            print(item);
            trans.add(item);
          }
        }
        }
      );
    }
  }

//Main class
body: TabBarView(
              controller: _tabController,
              children: <Widget>[
                new FutureBuilder<List<Transaction>>(
                  future: fetchBudgetTrans(new http.Client()),
                  builder: (context, snapshot) {
                    if (snapshot.hasError) print(snapshot.error);

                    if (snapshot.hasData) {
                      // BudgetDateRangePicker tl = new BudgetDateRangePicker(
                      //     transactions: snapshot.data);
                      BudgetDateRangePicker tl = new BudgetDateRangePicker(
                          transactions: snapshot.data);
                      return tl;
                    } else
                      return new Center(child: new CircularProgressIndicator());
                  },
                ),
//Model
class Transaction {
  final String to;
   DateTime date;
  final String amount;
  final String category;

  Transaction({this.to, this.date, this.amount, this.category});
  factory Transaction.fromJson(Map<String, dynamic> json) {
    return Transaction(
        to: json["to"] as String,
        date: json["date"] as DateTime,
        amount: json["amount"] as String,
        category: json["category"] as String);
  }
}
//GET REQUEST
Future<List<Transaction>> fetchBudgetTrans(http.Client client) async {
  final response =  await client.get(Uri.parse('http://192.168.191.1:8000/budget/trans'));
  // await client.get(Uri.parse('http://127.0.0.1:8000/budget/trans'));
  // Use the compute function to run parse response in a separate isolate
  return compute(parseDataBudget, response.body);
}


// A function that will convert a response body into a List<Stock>
List<Transaction> parseDataBudget(String responseBody) {
  final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
  return parsed
      .map<Transaction>((json) => new Transaction.fromJson(json))
      .toList();
}

Transaction.fromJson 工厂中,您将 json['date'] 的类型覆盖为 DateTime,但事实并非如此,因此您需要将 json 数据转换为本机 DateTime 类型。通常像 DateTime.fromMillisecondsSinceEpoch(json['date']?.toInt() ?? 0) 这样的东西对我来说效果很好。