Konstruktor fromJson
Termasuk bagian Data dan Jaringan dalam perjalanan Flutter di Coddy. Pelajaran 17 dari 27.
Membaca user['name'] as String di semua layar membuat kodemu berantakan, dan satu typo pada key bisa merusaknya. Solusi yang umum adalah menggunakan class untuk data tersebut, dengan satu constructor yang memahami JSON. Constructor ini disebut fromJson:
class User {
User({required this.name, required this.age});
final String name;
final int age;
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
);
}
}User.fromJson adalah named constructor, cara kedua untuk membuat User. Kata factory memungkinkan constructor menjalankan kode dan return object yang dibuatnya. Constructor biasa tidak bisa return apa pun.
Sekarang JSON dibaca di satu tempat. Bagian lain dari aplikasi mendapatkan User yang sebenarnya, dengan user.name bertipe String, dan typo akan menjadi compile error, bukan null:
final body = await fetch('/user');
return User.fromJson(jsonDecode(body));Hampir setiap aplikasi yang berkomunikasi dengan server memiliki fromJson untuk setiap jenis data yang diterimanya.
Tantangan
SulitProfil menampilkan Unknown: loadUser mengabaikan JSON. Tambahkan factory User.fromJson(Map<String, dynamic> json) pada User untuk membaca name, email, dan age, lalu buat loadUser mengembalikan User.fromJson(jsonDecode(body)). Impor dart:convert.
Coba sendiri
import 'package:flutter/material.dart';
import 'api.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: ProfileScreen(),
);
}
}
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
late Future<User> _user;
@override
void initState() {
super.initState();
_user = loadUser();
}
Future<User> loadUser() async {
final body = await fetch('/user');
print(body);
return User(name: 'Unknown', email: 'unknown', age: 0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: Center(
child: FutureBuilder<User>(
future: _user,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Could not load: ${snapshot.error}');
}
if (snapshot.hasData) {
final user = snapshot.data!;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
user.name,
style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(user.email, style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('${user.age} years old'),
],
);
}
return const CircularProgressIndicator();
},
),
),
);
}
}
class User {
User({required this.name, required this.email, required this.age});
final String name;
final String email;
final int age;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Data dan Jaringan
Latihan sendiri: Compiler Flutter online