How to sort/order a list by date in dart/flutter?

FlutterDart

Flutter Problem Overview


I have the following list, that I am trying to re-order/ sort by the DateTime.

import 'package:intl/intl.dart'; 
//don't forget to add under dependencies pubspec.yml "intl: ^0.15.8"


List products = [];

//adding into the new list from raw API list
for(final item in rawProducts){
   
   var parsedDate = DateTime.parse.(item['expiryDate']);
   tmpArray = {
     'id': item['id'],
     'name': item['name'],
     'price': item['price'],
     'expiry': parsedDate
   }
   products.add(tmpArray);
  }
}


List products = [

 {id: 1242, name: milk, price: $5, expiry: 2019-11-25 00:00:00:000},
 {id: 1242, name: egg, price: $2, expiry: 2019-11-22 00:00:00:000},
 {id: 1243, name: bread, price: $3, expiry: 2019-11-22 00:00:00:000},
 {id: 1244, name: butter, price: $7, expiry: 2019-11-24 00:00:00:000},
 {id: 1247, name: butter, price: $7, expiry: 2019-11-23 00:00:00:000},

]

I would like to re-order the list in a way that the farthest expiry date shows up first:

 25-11-2019
 24-11-2019
 23-11-2019
 22-11-2019
 22-11-2019

What I have tried (updated) -> SOLVED by changing a.expiry into a['expiry'] :

  products.sort((a,b) {
    var adate = a['expiry'] //before -> var adate = a.expiry;
     var bdate = b['expiry'] //var bdate = b.expiry;
     return -adate.compareTo(bdate);
  });

on the sort function I am receiving this error (SOLVED by above fix):

Unhandled Exception: NoSuchMethodError: Class 
'_InternalLinkedHashMap<String, dynamic>'has no instance getter 'expiry'.

Flutter Solutions


Solution 1 - Flutter

In your example above, expiry is a String, not a DateTime object. You have a few options here, depending on what you want to achieve.

The easiest solution would be to use String's built in compareTo method, which allows sorting Strings. Those timestamps are already in a sortable format, so this would work:

products.sort((a,b) {
    return a.compareTo(b);
 });

Or more concise:

products.sort((a,b) => a.compareTo(b));

This is pretty basic. Like pskink mentioned in the comment, building on this you could convert the Strings to actual DateTime objects.

DateTime expiryAsDateTime = DateTime.parse(expiry);

DateTime also has a built in compareTo method, so the code snippet above would work with DateTimes as well as Strings.

If you want to reverse the order, just swap a and b.

Solution 2 - Flutter

I fixed it by changing changing a.expiry into a['expiry'] and b.expiry into b['expiry']

products.sort((a,b) {
 var adate = a['expiry'] //before -> var adate = a.expiry;
 var bdate = b['expiry'] //before -> var bdate = b.expiry;
 return adate.compareTo(bdate); //to get the order other way just switch `adate & bdate`
});

Solution 3 - Flutter

convert to DateTime

import 'package:intl/intl.dart';

void main() {
  List products = [
    "2019-11-25 00:00:00.000",
    "2019-11-22 00:00:00.000",
    "2019-11-22 00:00:00.000",
    "2019-11-24 00:00:00.000",
    "2019-11-23 00:00:00.000"
  ];
  List<DateTime> newProducts = [];
  DateFormat format = DateFormat("yyyy-MM-dd");

  for (int i = 0; i < 5; i++) {
    newProducts.add(format.parse(products[i]));
  }
  newProducts.sort((a,b) => a.compareTo(b));

  for (int i = 0; i < 5; i++) {
    print(newProducts[i]);
  }
}

without convert to DateTime

import 'package:intl/intl.dart';

void main() {
  List products = [
    "2019-11-25 00:00:00.000",
    "2019-11-22 00:00:00.000",
    "2019-11-22 00:00:00.000",
    "2019-11-24 00:00:00.000",
    "2019-11-23 00:00:00.000"
  ];

  products.sort((a,b) => a.compareTo(b));

  for (int i = 0; i < 5; i++) {
    print(products[i]);
  }
}

Solution 4 - Flutter

If you have something like:

{
"id": 100,
"timestamp": "2021-02-02T15:15:11Z",
"name": "Entry1"
}

Then do this:

List<Values> _myList = [];
_myList.sort((a,b)=> a["timestamp"].compareTo(b["timestamp"])); 

Or like in my code:

task.sort((a,b) => a.createdAt.compareTo(b.createdAt));

Source

Solution 5 - Flutter

If we get more specific then try like this one.

its worked perfectly for me


transactionList.sort((a, b) {
  int aDate = DateTime.parse(a.dateTime ?? '').microsecondsSinceEpoch;
  int bDate = DateTime.parse(b.dateTime ?? '').microsecondsSinceEpoch;
  return aDate.compareTo(bDate);
});

Solution 6 - Flutter

If you want to sort the objects by a property name without having to use DateTime assuming the date and time is a string, do this:

products.sort((a, b)=> a['expiry'].compareTo(b['expiry']));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManasView Question on Stackoverflow
Solution 1 - FlutterMichaelMView Answer on Stackoverflow
Solution 2 - FlutterManasView Answer on Stackoverflow
Solution 3 - Flutteruser9139407View Answer on Stackoverflow
Solution 4 - FlutterpaakjisView Answer on Stackoverflow
Solution 5 - FlutterSaiful IslamView Answer on Stackoverflow
Solution 6 - FlutterMosesAyoView Answer on Stackoverflow