I have an app where I am trying to convert custom objects that the user inputs to and from JSON so I can store them in shared preferences.
Each object is a 'Resolution' and has multiple property types (Dates, Colors etc...) which I have no problem converting. So far so good...
My problem is that one of its properties is a List of type 'Commitment'. A 'Commitment' is ANOTHER custom object which also has properties of many different types (dates, doubles, strings etc..).
I've discovered I cannot simply convert the whole List property into a string and back, I need to run a specific conversion for all of the individual properties within each commitment within the list.
So I've basically got a nested conversion requirement...
The code for my 'RESOLUTION' is as follows
class Resolution {
final String id;
String title;
late DateTime? startDate;
late DateTime? endDate;
Color color;
double progress;
List<Commitment> commitments;
bool isComplete;
Resolution(
{required this.id,
required this.title,
this.startDate,
required this.endDate,
this.color = Colors.orange,
this.progress = 0,
this.commitments = const [],
this.isComplete = false});
Map toMap() {
return {
'id': id,
'title': title,
'startDate': startDate!.toIso8601String(),
'endDate': endDate!.toIso8601String(),
'color': color.value.toString(),
'progress': progress,
'commitments': convertCommitmentsToJSON(commitments),
'isComplete': isComplete,
};
}
Resolution.fromMap(Map map)
: id = map['id'],
title = map['title'],
startDate = DateTime.tryParse(map['startDate']),
endDate = DateTime.tryParse(map['endDate']),
color = Color(int.parse(map['color'])),
progress = map['progress'],
commitments = List<Commitment>.from(map['commitments']),
isComplete = map['isComplete'];
convertCommitmentsToJSON(commitments) {
for (Commitment commitment in commitments) {
commitment.toMap();
}
}
This works perfectly EXCEPT when it comes to that List Commitment property... As you can see I have written the following method
convertCommitmentsToJSON(commitments) {
for (Commitment commitment in commitments) {
commitment.toMap();
}
}
Which I THINK is successfully converting the list to JSON by looping through the list contents and applying a conversion method I have created within the COMMITMENT class.
Assuming I have that half of the problem solved (which I may not so feel free to chip in), my issue is converting that JSON back into a list of Commitment objects...
I tried the following...
convertCommitmentsFromJSON(List<Commitment> list) {
for (Commitment commitment in list) {
commitment.fromMap(jsonDecode(commitment));
}
}
...but I get the message 'The static method 'fromMap' can't be accessed through an instance'
The content of my (simplified) COMMITMENT class is as follows if it helps
class Commitment {
String description;
DateTime? endDate;
Commitment({required this.description, this.endDate});
Map<String, dynamic> toMap() => {
'description': description,
'endDate': endDate?.toIso8601String(),
};
static Commitment fromMap(Map<String, dynamic> json) => Commitment(
description: json['description'],
endDate: DateTime.tryParse(json['endDate']),
);
}
Can anyone help? I'm relatively new to coding so perhaps i'm completely down the wrong path
REVISED CONVERSION CODE
Map toJson() {
return {
'id': id,
'title': title,
'startDate': startDate!.toIso8601String(),
'endDate': endDate!.toIso8601String(),
'color': color.value.toString(),
'progress': progress,
'commitments': convertCommitmentsToJSON(commitments),
'isComplete': isComplete,
};
}
Resolution.fromJson(Map map)
: id = map['id'],
title = map['title'],
startDate = DateTime.tryParse(map['startDate']),
endDate = DateTime.tryParse(map['endDate']),
color = Color(int.parse(map['color'])),
progress = map['progress'],
commitments = convertCommitmentsFromJSON(List<Commitment>.from(map['commitments'])),
isComplete = map['isComplete'];
convertCommitmentsToJSON(commitments) {
for (Commitment commitment in commitments) {
commitment.toJson();
}
}
convertCommitmentsFromJSON(List<Commitment> list) {
for (Commitment commitment in list) {
Commitment.fromJson;
}
}
Managed to resolve in the end with Kevin's help. syntax aside a key thing i was missing is that i wasn't actually returning a list in the original version of this function. I was simply looping through and doing nothing with the output.
Kevin, thanks for the assist. Got there in the end! ;)
static List<Commitment> convertCommitmentsFromJSON(List<dynamic> list) {
List<Commitment> commitmentsList = [];
if (list.isNotEmpty) {
for (var item in list) {
Commitment commitment = Commitment.fromJson(item);
commitmentsList.add(commitment);
}
}
return commitmentsList;
}