Search code examples
jsonflutterdartencode

How to decode JSON to a Map<DateTime, List<Object>>


I can't figure out how to decode a JSON to a specific Map.

First of all I have a map that stores the date as the map key, and the value is a list of objects. I also made custom methods to convert the objects to JSON. The class model for the list of objects is:

class Task {
  late int taskId;
  late bool isCompleted;
  late String text;
  late PriorityItem priority;


Map<String, dynamic> toJson() =>
    {
      "id": taskId,
      "isCompleted": isCompleted,
      "text": text,
      "priority": priority.toString(),
    };

factory Task.fromJson(Map<String, dynamic> json) =>
    Task(
        json["isCompleted"],
        taskId:json["id"],
        text: json["text"],
        priority: json["priority"]);

}

enum PriorityItem{
  low,
  medium,
  high
}

The map is stored inside another class called TaskList as

static LinkedHashMap<DateTime, List<Task>> weeklyTaskMap = LinkedHashMap<DateTime, List<Task>>();


static Map<String, dynamic> toJson(LinkedHashMap<DateTime, List<Task>> taskMap) {
  Map<String, dynamic> myMap = {};

  taskMap.forEach((key, value) { 
    myMap[key.toIso8601String()] = List<dynamic>.from(value.map((x) => x.toJson()));
  });

  return myMap;
}

static LinkedHashMap<DateTime, List<Task>> fromJson(Map<String, dynamic> json) {
  LinkedHashMap<DateTime, List<Task>> myMap = {} as LinkedHashMap<DateTime, List<Task>>;
  json.forEach((key, value) {
    myMap[DateTime.parse(key)] = List<Task>.from(json[value]
        .map((x) => Task.fromJson(value)));
  });

  return myMap;
}

Encoding the map to JSON is working just fine, this would be an output after encoding the map:

{
    "2022-11-14T15:38:52.879009": [
        {
            "id": 0,
            "isCompleted": false,
            "text": "how to get rid ",
            "priority": "PriorityItem.medium"
        },
        {
            "id": 1,
            "isCompleted": false,
            "text": "good morning and I ",
            "priority": "PriorityItem.low"
        }
    ],
    "2022-11-15T00:00:00.000Z": [
        {
            "id": 2,
            "isCompleted": false,
            "text": "how to get rid of the ",
            "priority": "PriorityItem.high"
        }
    ]
}

Methods used to encode and decode:

void getMapsFromPrefs() async {
  SharedPreferences getMaps = await _prefs;

  Map dailyMap = TaskList.fromJson(jsonDecode(getMaps.getString('daily')!));
  LinkedHashMap<DateTime, List<Task>> weeklyMap = jsonDecode(getMaps.getString('weekly')!);

  TaskList.taskMap = dailyMap;
  TaskList.weeklyTaskMap = weeklyMap;
}

void saveMapsToPrefs() async {
  SharedPreferences getMaps = await _prefs;
  getMaps.clear();
  var dailyTasksJson = json.encode(TaskList.toJson(TaskList.taskMap));
  var weeklyTasksJson = json.encode(TaskList.toJson(TaskList.weeklyTaskMap));

  getMaps.setString('daily', dailyTasksJson);
  getMaps.setString('weekly', weeklyTasksJson);

  print("saved ${getMaps.getString('daily')}");
}

The only problem I have is decoding the JSON to my desired Map. I hope this is understandable, if anyone needs extra information please feel free to ask :) Thank you.


Solution

  • The issue was inside the fromJson() function, I was generating the list from an invalid variable

    Updated method:

    static LinkedHashMap<DateTime, List<Task>> fromJson(Map<String, dynamic> json) {
        LinkedHashMap<DateTime, List<Task>> tempMap = LinkedHashMap<DateTime, List<Task>>();
        json.forEach((key, value) {
          tempMap.addAll({DateTime.parse(key): **List<Task>.from(value.map((x) => Task.fromJson(x)))**
          });
        });
        return tempMap;
      }