How to regroup JSON to match data types in Flutter?

834

Let you have data in the following format:

List<Map<String, dynamic>> articlesListJson = [
  {
    "id": 1,
    "name": "Article 1",
    "created_at": "2020-08-01T00:30:00.000000Z",
  },
  {
    "id": 2,
    "name": "Article 2",
    "created_at": "2020-08-01T00:45:00.000000Z",
  },
  {
    "id": 3,
    "name": "Article 3",
    "created_at": "2020-08-02T00:00:00.000000Z",
  },
];

(If you have a json string instead, use jsonDecode function to parse it to Dart's List of Map's).

As you want to store dates as dd.mm.yyyy String, write a helper function for converting 2020-08-01T00:30:00.000000Z to 01.08.2020:

String extractDateString(String dateTimeString) {
  DateTime dateTime = DateTime.parse(dateTimeString);
  String day = dateTime.day.toString().padLeft(2, '0');
  String month = dateTime.month.toString().padLeft(2, '0');
  String year = dateTime.year.toString().padLeft(4, '0');
  return '$day.$month.$year';
}

Then you'll be able to group the list by date:

Map<String, List<Map<String, dynamic>>> articleGroupsJson = groupBy(
  articlesListJson,
  (a) => extractDateString(a['created_at']),
);
// {'01.08.2020': [{...}, {...}], '02.08.2020': [{...}]}

groupBy is from collection package. Depend on it or just copy-paste function source.

Now parse each Map<String, dynamic> to Article class:

class Article {
  int id;
  String name;
  
  Article({this.id, this.name});
}

in a standard way:

Article parseArticle(Map<String, dynamic> map) {
  return Article(
    id: map['id'],
    name: map['name'],
  );
}

Because the data is already groupped, instead of simply mapping the list you'll need to map groups, and for each group map its value (which is list)

Map<String, List<Article>> articleGroups = articleGroupsJson.map(
  (date, list) => MapEntry(
    date,
    list.map(parseArticle).toList(),
  ),
);

Now articleGroups has the structure you want

Share:
834
ImaFirinMahLazer
Author by

ImaFirinMahLazer

Updated on December 23, 2022

Comments

  • ImaFirinMahLazer
    ImaFirinMahLazer over 1 year

    The goal here is to group JSON data by date and convert it into object in Flutter.

    API of service I'm using returns JSON in this format:

            {
                "id": 1,
                "name": "Article Name",
                "created_at": "2020-01-10T00:33:09.000000Z",
            },
            {
                "id": 2,
                "name": "Article Name",
                "created_at": "2020-01-10T00:33:09.000000Z",
            },
    

    I need to convert it to following format:

      Map<String, List<Article>> ArticleHistory = {
        '04.08.2020': [
          Article(id: 16, name: 'Article Name'),
          Article(id: 15, name: 'Article Name'),
          Article(id: 14, name: 'Article Name'),
          Article(id: 13, name: 'Article Name'),
        ],
        '03.08.2020': [
          Article(id: 12, name: 'Article Name'),
          Article(id: 11, name: 'Article Name'),
          Article(id: 10, name: 'Article Name'),
          Article(id: 9, name: 'Article Name'),
        ],
        '02.08.2020': [
          Article(id: 8, name: 'Article Name'),
          Article(id: 7, name: 'Article Name'),
          Article(id: 6, name: 'Article Name'),
          Article(id: 5, name: 'Article Name'),
        ],
        '01.08.2020': [
          Article(id: 4, name: 'Article Name'),
          Article(id: 3, name: 'Article Name'),
          Article(id: 2, name: 'Article Name'),
          Article(id: 1, name: 'Article Name'),
        ],
      };        
    

    How that can be achieved?

    • Pavel
      Pavel over 3 years
      Are you sure you want map key be String, not DateTime?
    • ImaFirinMahLazer
      ImaFirinMahLazer over 3 years
      Yeah, sure thing
  • Pavel
    Pavel over 3 years
    Note that if you use String to represent date in Map keys, the behavior might depend on device's time zone
  • Pavel
    Pavel over 3 years
    Also instead of manual DateTime formatting, intl package can be used