Halo teman-teman pada artikel sebelumnya kita sudah menghubungkan flutter dengan supabase, sekarang kita akan membuat service untuk akses ke database agar lebih rapi dalam memanage aplikasi.
Membuat Model Data
Sekarang kita akan membuat model data, dari model data ini nanti kita bisa mudah dalam mengelola data dari database supabase. Sekarang kita buat folder dengan nama model
di dalam folder /lib
lalu di dalam folder /lib/model
kita buat file dengan nama todo_model.dart
, lalu kita ketik kode berikut:
class TodoModel {
final String id;
final String title;
final bool isDone;
TodoModel({required this.id, required this.title, required this.isDone});
factory TodoModel.fromJson(Map<String, dynamic> json) {
return TodoModel(
id: json['id'],
title: json['title'],
isDone: json['is_done'],
);
}
static List<TodoModel> fromJsonToList(List<dynamic> jsonList) {
return jsonList.map((json) => TodoModel.fromJson(json)).toList();
}
}
Membuat Service Todo
Sekarang kita membuat Service untuk mengelola akses database, yang di mana di dalam service ini berhubungan dengan langsung dengan database supabase. Teman-teman buat folder dengan nama service
di dalam folder /lib/
, lalu di dalam folder /lib/service
kita buat file dengan nama todo_service.dart
, lalu kita ketik kode berikut:
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:todo_list_supabase/model/todo_model.dart';
class TodoService {
final _client = Supabase.instance.client;
Future<List<TodoModel>> fetchTodos() async {
return run(() async {
final response = await _client
.from('todos')
.select()
.order('created_at', ascending: false);
return TodoModel.fromJsonToList(response);
});
}
Future<void> addTodo(String title) async {
return run(() async {
await _client.from('todos').insert({
'title': title,
'is_done': false,
'created_at': DateTime.now().toIso8601String(),
});
});
}
Future<void> toggleDone(String id, bool isDone) async {
return run(() async {
await _client.from('todos').update({'is_done': !isDone}).eq('id', id);
});
}
Future<void> deleteTodo(String id) async {
return run(() async {
await _client.from('todos').delete().eq('id', id);
});
}
Future<T> run<T>(Future<T> Function() function) async {
try {
return await function();
} on PostgrestException catch (error) {
throw ServerException(message: error.message);
} catch (error) {
throw ServerException(message: error.toString());
}
}
}
class ServerException implements Exception {
final String message;
ServerException({this.message = 'Server error'});
}
Perubahan kode di atas:
1. Import
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:todo_list_supabase/todo_model.dart';
- Mengimpor package Supabase Flutter untuk akses database.
- Mengimpor
TodoModel
untuk konversi data JSON dari Supabase menjadi objek model.
2. TodoService Class
class TodoService {
final _client = Supabase.instance.client;
TodoService
adalah class untuk berinteraksi dengan tabel todos
di Supabase.
Supabase.instance.client
adalah koneksi ke database Supabase.
3. fetchTodos()
Future<List<TodoModel>> fetchTodos() async {
return run(() async {
final response = await _client
.from('todos')
.select()
.order('created_at', ascending: false);
return TodoModel.fromJsonToList(response);
});
}
- Mengambil semua todo dari tabel
todos
.
- Mengurutkan berdasarkan
created_at
(data terbaru muncul pertama).
TodoModel.fromJsonToList
mengubah hasil query (JSON) menjadi List<TodoModel>
.
4. addTodo()
Future<void> addTodo(String title) async {
return run(() async {
await _client.from('todos').insert({
'title': title,
'is_done': false,
'created_at': DateTime.now().toIso8601String(),
});
});
}
- Menambahkan todo baru ke tabel.
- Default
is_done
diset ke false
.
created_at
menyimpan waktu sekarang dalam format ISO8601.
5. toggleDone()
Future<void> toggleDone(String id, bool isDone) async {
return run(() async {
await _client.from('todos').update({'is_done': !isDone}).eq('id', id);
});
}
- Mengubah status selesai (
is_done
) sebuah todo.
!isDone
membalik status (jika true
jadi false
, dan sebaliknya).
eq('id', id)
memastikan hanya row dengan id
yang sesuai yang diupdate.
6. deleteTodo()
Future<void> deleteTodo(String id) async {
return run(() async {
await _client.from('todos').delete().eq('id', id);
});
}
- Menghapus todo berdasarkan
id
.
7. run()
Future<T> run<T>(Future<T> Function() function) async {
try {
return await function();
} on PostgrestException catch (error) {
throw ServerException(message: error.message);
} catch (error) {
throw ServerException(message: error.toString());
}
}
- Sebuah helper untuk menangani error.
- Jika query Supabase melempar
PostgrestException
, error dibungkus dengan ServerException
.
- Semua error lain juga di-handle agar service tetap mengembalikan exception yang seragam.
8. ServerException
class ServerException implements Exception {
final String message;
ServerException({this.message = 'Server error'});
}
- Custom exception untuk memberikan pesan error yang lebih jelas saat operasi database gagal.
Kesimpulan
Pada tutorial kali ini kita belajar bagaimana membuat service untuk berkomunikasi dengan database supabase dan membuat data model untuk mengelola data dari database supabase. Langkah selanjutnya nanti kita akan membuat State Management dengan BLoC.
Ebook Premium
Membangun Dashboard dan Aplikasi Android Food Store Dengan Laravel Filament, Flutter dan Payment Gateway
Membangun Aplikasi Donasi Online dengan Laravel, Flutter dan Payment Gateway