Reputation: 229
What is the best way to unmarshall this json in dart:
{
"Ace-spades-2": {
"rank": { "shortName": "A", "longName": "Ace" },
"suit": { "name": "spades" },
"id": "Ace-spades-2"
},
"Two-spades-2": {
"rank": { "shortName": "2", "longName": "Two" },
"suit": { "name": "spades" },
"id": "Two-spades-2"
},
"Three-spades-2": {
"rank": { "shortName": "3", "longName": "Three" },
"suit": { "name": "spades" },
"id": "Three-spades-2"
},
{....a bunch more cards}
}
Here are my classes that I want to unmarshall into. Specifically I want to make the data Map<String,Card>. How can I do this?
class Card {
Rank rank;
Suit suit;
String id;
Card({this.rank,this.suit,this.id})
}
class Rank {
String shortName;
String longName;
Rank({this.shortName, this.longName});
}
class Suit {
String name;
Suit({this.name});
}
In Go, I would just do cards := map[string]Card{} json.Unmarshal(<some_json>, &cards).
What is the best way to do this in dart?
Upvotes: 2
Views: 676
Reputation: 1988
For serialization in Flutter (where reflection is not available) is very common to use the json_serializable package. A good tutorial about this package is also in the flutter doc: https://flutter.dev/docs/development/data-and-backend/json#serializing-json-using-code-generation-libraries
When you have annotated yours classes (and you have completed the others installation instructions - also remember the annotation on the library
declaration, which is mandatory), you can take advantage of the Card.fromJson()
factory constructor. You can convert your json raw String in a Map<String, dynamic>
using the jsonDecode()
function (of the dart:convert
package), then iterate on the Map and convert every entry in the Map with Card.fromJson
.
For example:
Map<String, Card> cardMap = (jsonDecode(jsonString) as Map<String, dynamic>).map((key, cardString) => MapEntry(key, Card.fromJson(cardString)));
A very important note: when you have a class (Card and Rank, in your example) with fields whose type is not primitive, but instead represents another class annotated with JsonSerializable, the JsonSerializable annotation must pass explicitToJson: true (i.e. @JsonSerializable(explicitToJson: true) class Card
).
The process to serialize class/deserialize json the first time isn't as fast as in Go, but flutter doesn't have reflection.
Upvotes: 2