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)
这样的东西对我来说效果很好。
我尝试按日期过滤 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)
这样的东西对我来说效果很好。