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
Posting Komentar