HTTP GET: Mengambil Data dari API
Ambil data JSON dari REST API dengan package http, tampilkan dengan FutureBuilder yang rapi.
Setup package http
Tambahkan dependensi di pubspec.yaml:
dependencies:
http: ^1.2.0Lalu flutter pub get. Package http adalah cara standar dan ringan untuk request HTTP di Flutter.
GET request dasar
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<List<Produk>> ambilProduk() async {
final uri = Uri.parse('https://api.contoh.id/produk');
final response = await http.get(uri);
if (response.statusCode == 200) {
final List<dynamic> jsonList = jsonDecode(response.body) as List<dynamic>;
return jsonList
.map((e) => Produk.fromJson(e as Map<String, dynamic>))
.toList();
}
throw Exception('Gagal memuat produk: ${response.statusCode}');
}Selalu cek statusCode sebelum parsing body. Melempar Exception saat gagal membuat FutureBuilder bisa menampilkan state error dengan rapi.
Menampilkan di UI
class _DaftarState extends State<Daftar> {
late final Future<List<Produk>> _futureProduk;
@override
void initState() {
super.initState();
_futureProduk = ambilProduk();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Produk>>(
future: _futureProduk,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Error: ${snapshot.error}'),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => setState(() => _futureProduk = ambilProduk()),
child: const Text('Coba lagi'),
),
],
),
);
}
final produk = snapshot.data ?? [];
return ListView.builder(
itemCount: produk.length,
itemBuilder: (context, i) => ListTile(title: Text(produk[i].nama)),
);
},
);
}
}Tombol "Coba lagi" membuat Future baru di dalam setState, pola refresh manual yang bersih.
Timeout: jangan gantung selamanya
Request tanpa timeout bisa menggantung kalau server tidak merespons. Tambahkan batas waktu:
final response = await http.get(uri).timeout(
const Duration(seconds: 10),
onTimeout: () => throw Exception('Request timeout, periksa koneksi'),
);Catatan teknis: Di Android, request ke
http://(bukan https) diblokir secara default oleh network security config, dan di iOS oleh App Transport Security. Untuk development ke API lokal, pakaihttpsatau atur exception khusus, jangan asal menonaktifkan keamanan di production. Juga, alamatlocalhostdari emulator Android bukan komputermu, pakai10.0.2.2untuk menjangkau server lokal dari emulator.