Bir fromJson Kurucusu
Coddy'nin Flutter Journey'sinin Veri ve Ağ bölümünün bir parçası. Ders 17 / 27.
Ekranlarının her yerinde user['name'] as String okumak karmaşaya yol açar ve anahtardaki tek bir yazım hatası bunu bozar. Genellikle çözüm, veriler için JSON'u tanıyan tek bir yapıcıya sahip bir sınıf oluşturmaktır. Buna fromJson denir:
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, ikinci bir User oluşturma yolu olan adlandırılmış bir yapıcıdır. factory sözcüğü, bir yapıcının kod çalıştırmasına ve oluşturduğu nesneyi return etmesine olanak tanır. Sıradan bir yapıcı hiçbir şey return edemez.
Artık JSON tek bir yerde okunuyor. Uygulamanın geri kalanı, user.name değerinin bir String olduğu gerçek bir User elde ediyor; yazım hatası da null yerine derleme hatasına yol açıyor:
final body = await fetch('/user');
return User.fromJson(jsonDecode(body));Sunucuyla iletişim kuran hemen hemen her uygulamada, aldığı her veri türü için bir fromJson bulunur.
Görev
ZorProfilde Unknown yazıyor: loadUser, JSON'ı yok sayıyor. User sınıfına factory User.fromJson(Map<String, dynamic> json) ekleyerek name, email ve age değerlerini okumasını sağla ve loadUser işlevinin User.fromJson(jsonDecode(body)) döndürmesini sağla. dart:convert paketini içe aktar.
Kendin dene
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;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Veri ve Ağ bölümündeki tüm dersler
3Çağrılar Başarısız Olduğunda
try ile Hataları YakalamaHata Fırlatmafinally ile TemizlemeFutureBuilder Hata DurumuYeniden Dene DüğmesiKendi başına pratik yap: Online Flutter derleyicisi