Flutter JSON Parsing
Converting JSON data to Dart objects
📦 What is JSON Parsing?
JSON parsing converts JSON strings from APIs into Dart objects you can use in your app. Flutter provides built-in tools to decode JSON and map it to custom classes.
import 'dart:convert';
// JSON string
String jsonString = '{"name": "John", "age": 25}';
// Parse to Map
Map<String, dynamic> user = json.decode(jsonString);
print(user['name']); // John
Output:
John
JSON Parsing Methods
json.decode()
Convert JSON string to Map
Map data = json.decode(
'{"id": 1, "name": "Alice"}'
);
json.encode()
Convert Map to JSON string
String jsonStr = json.encode({
'id': 1,
'name': 'Alice'
});
Model Classes
Create custom Dart classes
class User {
final int id;
final String name;
User.fromJson(Map json);
}
Code Generation
Auto-generate parsing code
@JsonSerializable()
class User {
final String name;
}
🔹 Basic JSON Parsing
Parse simple JSON objects:
import 'dart:convert';
void parseSimpleJson() {
// JSON string
String jsonString = '''
{
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
''';
// Decode JSON
Map<String, dynamic> user = json.decode(jsonString);
// Access values
print('Name: ${user['name']}');
print('Email: ${user['email']}');
print('Age: ${user['age']}');
}
Output:
🔹 Parsing JSON Arrays
Handle lists of JSON objects:
void parseJsonArray() {
String jsonString = '''
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
{"id": 3, "name": "Charlie"}
]
''';
// Decode to List
List<dynamic> users = json.decode(jsonString);
// Loop through users
for (var user in users) {
print('ID: ${user['id']}, Name: ${user['name']}');
}
}
Output:
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: Charlie
🔹 Creating Model Classes
Convert JSON to type-safe Dart objects:
class User {
final int id;
final String name;
final String email;
User({
required this.id,
required this.name,
required this.email,
});
// Factory constructor for JSON parsing
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
email: json['email'],
);
}
// Convert to JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
}
// Usage
String jsonString = '{"id": 1, "name": "Alice", "email": "[email protected]"}';
User user = User.fromJson(json.decode(jsonString));
print(user.name); // Alice
Output:
Alice
🔹 Nested JSON Parsing
Handle complex nested structures:
class Address {
final String street;
final String city;
Address({required this.street, required this.city});
factory Address.fromJson(Map<String, dynamic> json) {
return Address(
street: json['street'],
city: json['city'],
);
}
}
class User {
final String name;
final Address address;
User({required this.name, required this.address});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'],
address: Address.fromJson(json['address']),
);
}
}
// Parse nested JSON
String jsonString = '''
{
"name": "John",
"address": {
"street": "123 Main St",
"city": "New York"
}
}
''';
User user = User.fromJson(json.decode(jsonString));
print('${user.name} lives in ${user.address.city}');
Output:
John lives in New York
🔹 Using json_serializable
Auto-generate parsing code with annotations:
# pubspec.yaml
dependencies:
json_annotation: ^4.8.1
dev_dependencies:
build_runner: ^2.4.6
json_serializable: ^6.7.1
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final int id;
final String name;
@JsonKey(name: 'email_address')
final String email;
User({required this.id, required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) =>
_$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
// Run: flutter pub run build_runner build
Benefits of json_serializable:
- Reduces boilerplate code
- Type-safe parsing
- Handles complex nested objects
- Custom field name mapping
🔹 Error Handling
Handle JSON parsing errors safely:
User? parseUser(String jsonString) {
try {
Map<String, dynamic> json = jsonDecode(jsonString);
return User.fromJson(json);
} catch (e) {
print('Error parsing JSON: $e');
return null;
}
}
// Usage
String invalidJson = '{"name": "John"'; // Missing closing brace
User? user = parseUser(invalidJson);
if (user != null) {
print('User: ${user.name}');
} else {
print('Failed to parse user');
}
Output:
Error parsing JSON: FormatException
Failed to parse user