Menghubungkan aplikasi dengan API dan mengambil data eksternal

Untuk praktikum "Menghubungkan aplikasi dengan API dan mengambil data eksternal", aplikasi Dart Flutter yang cocok dan mudah dipahami pemula adalah:


Aplikasi Cuaca (Weather App) Sederhana

Deskripsi: Menampilkan data cuaca dari API eksternal seperti OpenWeatherMap berdasarkan nama kota.

Fitur:

  • Input nama kota

  • Fetch data cuaca via API

  • Tampilkan suhu, cuaca, dan ikon

Konsep yang Dipelajari:

  • HTTP request menggunakan http package

  • Parsing JSON

  • Penggunaan FutureBuilder

  • Penanganan input dan tampilan dinamis


Aplikasi List Berita (News App)

Deskripsi: Menampilkan daftar berita terkini menggunakan API seperti NewsAPI.org.

Fitur:

  • Ambil berita terkini

  • Tampilkan judul, gambar, dan deskripsi

  • Navigasi ke halaman detail berita

Konsep yang Dipelajari:

  • Ambil data list dari API

  • Gunakan ListView builder

  • Navigasi antar halaman


Aplikasi Quote Harian (Random Quote App)

Deskripsi: Menampilkan kutipan (quotes) motivasi secara acak dari API seperti type.fit/api/quotes

Fitur:

  • Tombol "Get New Quote"

  • Tampilkan quote dan author

  • Refresh konten dari API

Konsep yang Dipelajari:

  • HTTP GET

  • Update UI dengan setState

  • Parsing list JSON


Rekomendasi: Mulai dari Aplikasi Cuaca atau Quote

Kenapa?

  • Mudah dipahami 

  • API gratis dan tidak membutuhkan login/token

  • Bisa dikembangkan lebih lanjut (misalnya tambahkan fitur favorit, simpan offline, dll)


Kalau aplikasi Flutter (yang berjalan di Zapp.run) dengan input teks nama kota secara bebas—misalnya: "Cimahi", "New York", "Tokyo", dll—lalu cari koordinatnya (latitude & longitude) secara otomatis, kemudian gunakan itu untuk fetch cuaca dari Open-Meteo API.




✅ CARA MELAKUKANNYA

Gunakan API Geocoding seperti:

🌐 Open-Meteo Geocoding API

URL:

pgsql
https://geocoding-api.open-meteo.com/v1/search?name=NAMA_KOTA

Contoh:

pgsql
https://geocoding-api.open-meteo.com/v1/search?name=Bandung

Respon JSON akan berisi lat & lon dari nama kota tersebut. Setelah itu, kirim permintaan ke API cuaca utama.


💻 KODE FLUTTER (ZAPP.RUN-COMPATIBLE): Input Kota Bebas

dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
  runApp(const WeatherApp());
}

class WeatherApp extends StatelessWidget {
  const WeatherApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatefulWidget {
  const WeatherScreen({super.key});

  @override
  State<WeatherScreen> createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  String city = "";
  double? temperature;
  String? weatherDesc;
  String? errorMessage;

  Future<void> fetchWeather(String cityName) async {
    setState(() {
      errorMessage = null;
    });

    final geoUrl =
        'https://geocoding-api.open-meteo.com/v1/search?name=$cityName&count=1';
    final geoRes = await http.get(Uri.parse(geoUrl));

    if (geoRes.statusCode == 200) {
      final geoData = jsonDecode(geoRes.body);

      if (geoData['results'] != null && geoData['results'].isNotEmpty) {
        final lat = geoData['results'][0]['latitude'];
        final lon = geoData['results'][0]['longitude'];
        final resolvedName = geoData['results'][0]['name'];

        final weatherUrl =
            'https://api.open-meteo.com/v1/forecast?latitude=$lat&longitude=$lon&current_weather=true';

        final weatherRes = await http.get(Uri.parse(weatherUrl));

        if (weatherRes.statusCode == 200) {
          final weather = jsonDecode(weatherRes.body)['current_weather'];
          setState(() {
            city = resolvedName;
            temperature = weather['temperature'];
            weatherDesc = _getWeatherDescription(weather['weathercode']);
          });
        } else {
          setState(() {
            errorMessage = "Gagal mengambil data cuaca.";
          });
        }
      } else {
        setState(() {
          errorMessage = "Kota tidak ditemukan.";
        });
      }
    } else {
      setState(() {
        errorMessage = "Gagal mencari lokasi.";
      });
    }
  }

  String _getWeatherDescription(int code) {
    switch (code) {
      case 0:
        return 'Cerah';
      case 1:
      case 2:
      case 3:
        return 'Berawan';
      case 45:
      case 48:
        return 'Berkabut';
      case 51:
      case 53:
      case 55:
        return 'Gerimis';
      case 61:
      case 63:
      case 65:
        return 'Hujan';
      case 80:
      case 81:
      case 82:
        return 'Hujan Lebat';
      default:
        return 'Tidak diketahui';
    }
  }

  final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Cuaca Global")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(
                labelText: 'Masukkan nama kota',
                border: OutlineInputBorder(),
              ),
              onSubmitted: fetchWeather,
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => fetchWeather(_controller.text),
              child: const Text("Cari Cuaca"),
            ),
            const SizedBox(height: 30),
            if (errorMessage != null)
              Text(errorMessage!,
                  style: const TextStyle(color: Colors.red, fontSize: 16))
            else if (temperature != null && weatherDesc != null) ...[
              Text(
                city,
                style: const TextStyle(fontSize: 24),
              ),
              const SizedBox(height: 10),
              Text(
                'Suhu: ${temperature!.toStringAsFixed(1)}°C',
                style: const TextStyle(fontSize: 20),
              ),
              Text(
                'Kondisi: $weatherDesc',
                style: const TextStyle(fontSize: 20),
              ),
            ]
          ],
        ),
      ),
    );
  }
}


✅ Tambahkan di pubspec.yaml

yaml
name: cuaca_app
description: A simple weather app

environment:
  sdk: '>=2.17.0 <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.6


🔥 Fitur:

Link Demo Aplikasi : https://zmse06vwmsf0.zapp.page/#/
  • Input kota bebas seluruh dunia

  • Opsi fallback jika kota tidak ditemukan

  • Respon cepat karena pakai Open-Meteo & Geocoding resmi


Visit counter For Websites (Jumlah Pengunjung Halaman)


Share:

Tidak ada komentar:

Posting Komentar

Blogger Tricks

Blogger Themes