How to deserialize JSON responses in Flutter
Communication between a Flutter application and an API often involves handling JSON data. However, due to Dart's type safety, deserializing JSON into Dart objects can be challenging. In this post, we will explore how to effectively deserialize JSON responses in Flutter.
1. Deserialization
Deserialization in Flutter refers to the process of converting received JSON data into Dart objects. We will use an example of deserializing JSON data of rocket launches retrieved from the SpaceX API into a Launch
object or a list of Launch
objects.
To simplify the deserialization process in Flutter, I recommend using the json_serializable package, along with its dependencies json_annotation and build_runner. If you are unfamiliar with these packages or need a more detailed tutorial, please refer to my other post on how to fetch data from an API in Flutter using the SpaceX API.

For this example, we will create two Dart files:
- The
launch.dart
file, which contains aLaunch
model. - The
launch_client.dart
file, which contains aLaunchClient
.
Launch
The Launch.dart
file represents a Dart model for a Launch
object. It defines the structure and properties of a Launch
, including the flight number, name, and success status.
import 'package:json_annotation/json_annotation.dart';
part 'launch.g.dart';
@JsonSerializable()
class Launch {
const Launch({
required this.flightNumber,
required this.name,
this.success,
});
factory Launch.fromJson(Map<String, dynamic> json) =>
_$LaunchFromJson(json);
final int flightNumber;
final String name;
final bool? success;
}
In this code snippet, we define the Launch
class using Dart annotations. The @JsonSerializable
annotation indicates that the class can be serialized and deserialized from JSON using code generation. The class has required properties such as flightNumber
and name
, and an optional property success
. The fromJson
factory method is responsible for deserializing a JSON object into a Launch
instance.
LaunchClient
The LaunchClient
class is responsible for making HTTP requests to the SpaceX API and deserializing the JSON responses into Launch
objects.
import 'dart:convert';
import 'package:flutter_deserialize_json_response/models/launch.dart';
import 'package:http/http.dart' as http;
class LaunchClient {
LaunchClient({http.Client? httpClient})
: _httpClient = httpClient ?? http.Client();
final http.Client _httpClient;
Future<Launch> getLaunch() async {
final request = Uri.https('api.spacexdata.com', 'v5/launches/latest');
final response = await _httpClient.get(request);
final bodyJson = jsonDecode(response.body) as Map<String, dynamic>;
return Launch.fromJson(bodyJson);
}
Future<List<Launch>> getLaunches() async {
final request = Uri.https('api.spacexdata.com', 'v5/launches');
final response = await _httpClient.get(request);
final bodyJson = jsonDecode(response.body) as List;
return bodyJson
.map((json) => Launch.fromJson(json as Map<String, dynamic>))
.toList();
}
}
In this code snippet, we have the LaunchClient
class that handles the API communication. It uses the http package to send HTTP requests. The getLaunch
method retrieves the latest launch data from the SpaceX API by making a GET request to the appropriate endpoint. It then deserializes the JSON response into a Launch
object using the fromJson
method.
Similarly, the getLaunches
method retrieves a list of launch data by making a GET request to a different endpoint. It deserializes the JSON array response into a list of Launch
objects by iterating over the JSON objects and calling the fromJson
method for each.
1.1 Deserialize JSON object
In the LaunchClient
on line 15, we decode the JSON using the jsonDecode
function and cast it to a Map<String, dynamic>
. This is necessary for the fromJson
function of the Launch
model to correctly deserialize the JSON into a Dart object.
1.2 Deserialize JSON list of objects
Starting from line 23, we decode the JSON using jsonDecode
and cast it to a List
because we want to iterate over it. On line 26, we go through the list and call the fromJson
function on each JSON object.
Similar to before, we ensure that the fromJson
function receives the correct data type by casting it to a Map<String, dynamic>
. Finally, we use the .toList()
function to ensure that we return a list.
2. Conclusion
Deserializing JSON data in Flutter becomes much simpler with the assistance of the json_serializable package. By understanding how to cast JSON data into the appropriate types, you can effortlessly create Dart objects or lists of Dart objects from the JSON responses.