flutterhttpapiMenengah3 mnt baca

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:

yaml
dependencies:
  http: ^1.2.0

Lalu flutter pub get. Package http adalah cara standar dan ringan untuk request HTTP di Flutter.

GET request dasar

dart
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

dart
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:

dart
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, pakai https atau atur exception khusus, jangan asal menonaktifkan keamanan di production. Juga, alamat localhost dari emulator Android bukan komputermu, pakai 10.0.2.2 untuk menjangkau server lokal dari emulator.