aplikasi CRUD Flutter + MockAPI



Deskripsi Project

Project ini merupakan aplikasi CRUD Flutter yang terhubung dengan MockAPI sebagai backend dummy untuk pengelolaan data. Aplikasi dibangun menggunakan Flutter SDK dan package http untuk melakukan komunikasi dengan API.

Fungsi Utama

1. Create → Menambahkan data baru (misalnya nama dan email).

2. Read → Menampilkan daftar data yang tersimpan dari API.

3. Update → Mengubah data yang sudah ada melalui tombol edit.

4. Delete → Menghapus data melalui tombol hapus.

Teknologi yang Digunakan

Flutter 3.7.3 (beta) → Framework utama untuk membuat aplikasi cross-platform.

MockAPI → Layanan API dummy untuk menyimpan dan mengambil data.

http 0.13.6 → Package Flutter untuk melakukan request REST API (GET, POST, PUT, DELETE).

Alur Kerja Aplikasi

1. Saat aplikasi dijalankan, Flutter melakukan request GET ke endpoint MockAPI dan menampilkan daftar data.

2. Pengguna bisa menambahkan data baru menggunakan tombol +, yang akan mengirimkan request POST ke API.

3. Data yang sudah ada dapat diperbarui melalui tombol edit (ikon pensil) yang mengirimkan request PUT.

4. Jika pengguna menekan tombol hapus (ikon tempat sampah), maka akan dikirimkan request DELETE ke API.

Hasil yang Ditampilkan

Aplikasi menampilkan daftar user (nama & email) yang diambil dari endpoint MockAPI.

Data dapat dimanipulasi secara langsung (tambah, edit, hapus), dan hasilnya tersinkron dengan MockAPI.


Kode main.dart:

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TESTING DATABASE',
      theme: ThemeData(primarySwatch: Colors.indigo),
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // pastikan endpoint sesuai resource di MockAPI
  final String apiUrl =
      "https://68a3e316c123272fb9b0a830.mockapi.io/posts";

  List items = [];

  final TextEditingController nameController = TextEditingController();
  final TextEditingController emailController = TextEditingController();

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  Future<void> fetchData() async {
    final response = await http.get(Uri.parse(apiUrl));
    if (response.statusCode == 200) {
      setState(() {
        items = json.decode(response.body);
      });
    }
  }

  Future<void> createData(String name, String email) async {
    await http.post(
      Uri.parse(apiUrl),
      headers: {"Content-Type": "application/json"},
      body: json.encode({"name": name, "email": email}),
    );
    fetchData();
  }

  Future<void> updateData(String id, String name, String email) async {
    await http.put(
      Uri.parse("$apiUrl/$id"),
      headers: {"Content-Type": "application/json"},
      body: json.encode({"name": name, "email": email}),
    );
    fetchData();
  }

  Future<void> deleteData(String id) async {
    await http.delete(Uri.parse("$apiUrl/$id"));
    fetchData();
  }

  void showForm({String? id, String? name, String? email}) {
    if (id != null) {
      nameController.text = name ?? "";
      emailController.text = email ?? "";
    } else {
      nameController.clear();
      emailController.clear();
    }

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(id == null ? "Tambah Data" : "Edit Data"),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: nameController,
              decoration: const InputDecoration(labelText: "Name"),
            ),
            TextField(
              controller: emailController,
              decoration: const InputDecoration(labelText: "Email"),
            ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("Batal"),
          ),
          ElevatedButton(
            onPressed: () {
              if (id == null) {
                createData(nameController.text, emailController.text);
              } else {
                updateData(id, nameController.text, emailController.text);
              }
              Navigator.pop(context);
            },
            child: const Text("Simpan"),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("CRUD Flutter + MockAPI")),
      body: items.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: items.length,
              itemBuilder: (context, index) {
                final item = items[index];
                return Card(
                  child: ListTile(
                    title: Text(item["name"] ?? "No Name"),
                    subtitle: Text(item["email"] ?? "No Email"),
                    trailing: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        IconButton(
                          icon: const Icon(Icons.edit, color: Colors.orange),
                          onPressed: () => showForm(
                            id: item["id"],
                            name: item["name"],
                            email: item["email"],
                          ),
                        ),
                        IconButton(
                          icon: const Icon(Icons.delete, color: Colors.red),
                          onPressed: () => deleteData(item["id"]),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => showForm(),
        child: const Icon(Icons.add),
      ),
    );
  }
}


KODE pubspec.yaml:

name: crud_mockapi
description: A Flutter CRUD example with MockAPI.io
publish_to: "none"
version: 1.0.0+1

environment:
  sdk: ">=2.18.0 <4.0.0"

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.6

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

Komentar

Postingan Populer