Parsing JSON in Flutter
JSON is the most common data format you'll encounter when working with APIs. Dart makes parsing JSON easy with the built-in dart:convert library.
To parse a JSON string into a Dart object, use jsonDecode:
import 'dart:convert';
void main() {
const jsonString = '{"name": "Alice", "age": 25, "isStudent": false}';
final Map<String, dynamic> data = jsonDecode(jsonString);
print(data['name']); // Alice
print(data['age']); // 25
}
But working with raw maps is messy. The real power comes from creating model classes. You define a class with a fromJson factory constructor:
class User {
final String name;
final int age;
final bool isStudent;
User({
required this.name,
required this.age,
required this.isStudent,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
isStudent: json['isStudent'] as bool,
);
}
}
Now you can parse JSON with a clean, type-safe API:
final jsonString = '{"name": "Alice", "age": 25, "isStudent": false}';
final Map<String, dynamic> jsonMap = jsonDecode(jsonString);
final user = User.fromJson(jsonMap);
print(user.name); // Alice
// user.age = 30; // Error! age is final
To convert an object back to JSON, add a toJson method:
class User {
final String name;
final int age;
final bool isStudent;
User({
required this.name,
required this.age,
required this.isStudent,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
isStudent: json['isStudent'] as bool,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
'isStudent': isStudent,
};
}
}
// Usage
final user = User(name: 'Bob', age: 30, isStudent: true);
final jsonString = jsonEncode(user.toJson());
print(jsonString);
// {"name":"Bob","age":30,"isStudent":true}
Handling nested JSON works the same way — just chain your fromJson calls:
class Team {
final String teamName;
final User captain;
Team({required this.teamName, required this.captain});
factory Team.fromJson(Map<String, dynamic> json) {
return Team(
teamName: json['teamName'] as String,
captain: User.fromJson(json['captain'] as Map<String, dynamic>),
);
}
}
These patterns keep your code organized and make API data easy to work with throughout your app.
Try it Yourself ->