Manual JSON Serialization with fromJson/toJson
Manually map your Dart objects to JSON by writing your own `fromJson` and `toJson` methods. This is ideal for simple data models or quick prototypes where code generation is overkill.
WHY IT EXISTS: Dart lacks built-in reflection for performance, meaning it can't automatically convert a plain JSON map into a typed Dart object. Manual serialization is the most direct solution: you explicitly tell Dart how to perform this conversion, without needing extra libraries or build steps.
THE MENTAL MODEL: Think of it like packing a suitcase. Your Dart object is your organized clothing. The toJson method is you packing everything into a generic bag (a Map<String, dynamic>), where each item just has a string label. The fromJson factory constructor is you unpacking that bag, using the labels to put everything back into a structured, typed object.
HOW IT WORKS: You add two key pieces to your data class. First, a factory constructor, conventionally named fromJson, that accepts a Map<String, dynamic> and returns a new instance of your class. Inside, you read values from the map using their string keys. Second, an instance method named toJson that returns a Map<String, dynamic>. This method builds a map from the object's properties, ready to be encoded into a JSON string.
WHEN TO USE IT: This approach is perfect for small projects, quick prototypes, or when you only have a few simple data classes. It’s also the best choice when you need to handle oddly-structured JSON from an external API, as you can write custom logic inside fromJson to clean up or transform the incoming data.
WHEN NOT TO USE IT: Avoid manual serialization in large applications with many complex or nested models. The process is tedious and error-prone. A simple typo in a JSON key string (like 'userName' vs 'username') will not be caught by the compiler and will lead to a runtime error. For anything beyond simple cases, use a code generation library like json_serializable to ensure type safety and reduce boilerplate.
ONE CANONICAL EXAMPLE: A simple User class would have final String fields for name and email. It would define a factory constructor User.fromJson(Map<String, dynamic> json) which creates a User instance by extracting json['name'] and json['email']. It would also have a toJson() method that returns a map literal: {'name': name, 'email': email}.
Read the original → docs.flutter.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.