NoSuchMethodError: The method 'isBefore' was called on null

228

in the Transaction.fromJson factory you override the type of json['date'] as DateTime, but it isn't, so instead you need to convert the json data to the native DateTime type. Usually something like DateTime.fromMillisecondsSinceEpoch(json['date']?.toInt() ?? 0) works well for me.

Share:
228
NoName
Author by

NoName

Updated on December 29, 2022

Comments

  • NoName
    NoName over 1 year

    I try to filter the JSON data by date. I'm stuck with comparing the date. The input is a list from the GET request then convert to the actual data type to use( DateTime, String). After that, I will pick a range of dates then compare them to the date of an object in the list. I don't know why I always got errors about 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();
    }
    
    • Mahesh Jamdade
      Mahesh Jamdade almost 3 years
      can you add a sample response of the json in the question that you are trying to parse?
    • NoName
      NoName almost 3 years
      { "amount": "-105", "date": "2020-01-09", "to": "Unknown" }, { "amount": "-28", "date": "2020-01-30", "to": "Unknown" }, { "amount": "-59", "date": "2020-01-01", "to": "AH" }, { "amount": "-124", "date": "2020-01-03", "to": "JUMBO" },
  • NoName
    NoName almost 3 years
    t.millisecondsSinceEpoch > _fromDate.millisecondsSinceEpoch So is this the way to compare date? (t from JSON, _fromDate is DateTime object)
  • NoName
    NoName almost 3 years
    I still got Unhandled Exception: NoSuchMethodError: The getter 'millisecondsSinceEpoch' was called on null.