Main Menu

Membuat Aplikasi To-Do List dengan Flutter dan Supabase #5: State Management BLoC


👍 0 ❤️ 0 💡 0 🔥 0 🙌 0 🥳 0
Membuat Aplikasi To-Do List dengan Flutter dan Supabase #5: State Management BLoC

Halo teman-teman pada tutorial sebelumnya kita sudah membuat remote service untuk meng-akses database supabase, sekarang kita akan membuat State Management menggunakan BLoC. State Management BLoC digunakan untuk memisahkan antara logika bisnis dan UI sehingga kode yang kita buat bisa dapat di uji dan terstruktur.

Membuat BLoC Cubit

Karena kita membuat aplikasi yang simpel maka kita akan membuat State Management menggunakan Cubit. Sekarang teman-teman buat file dengan folder dengan nama cubit di dalam folder /lib/, lalu di dalam folder /lib/cubit kita buat file dengan nama todo_cubit.dart, lalu 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'});
}

Mari kita jelaskan bagian per bagian:

1. Import

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todo_list_supabase/model/todo_model.dart';
import 'package:todo_list_supabase/service/todo_service.dart';
  • flutter_bloc: untuk manajemen state dengan Cubit.
  • todo_model.dart: model data untuk todo.
  • todo_service.dart: service yang mengakses database (Supabase).

2. Definisi TodoCubit

class TodoCubit extends Cubit<List<TodoModel>> {
  final TodoService _service;

  TodoCubit(super.initialState, this._service);
  • TodoCubit meng-extend Cubit<List<TodoModel>>, artinya state-nya adalah List<TodoModel> (daftar todo).
  • _service adalah instance dari TodoService, untuk memanggil fungsi CRUD ke database.
  • Constructor menerima:
    • initialState: biasanya berupa [] (list kosong).
    • _service: service untuk komunikasi database.

3. fetchTodos()

Future<void> fetchTodos() async {
  try {
    final todos = await _service.fetchTodos();
    emit(todos);
  } catch (e) {
    emit(state); // Tetap gunakan state lama jika error
    rethrow;
  }
}
  • Mengambil semua todo dari Supabase lewat TodoService.
  • Hasilnya di-emit ke state agar UI ter-update.
  • Jika error, tetap memakai state lama dan melempar error (rethrow) supaya bisa ditangani di UI (misalnya menampilkan snackbar).

4. addTodo()

Future<void> addTodo(String title) async {
  try {
    await _service.addTodo(title);
    await fetchTodos(); // Refresh daftar setelah menambah
  } catch (e) {
    emit(state);
    rethrow;
  }
}
  • Menambahkan todo baru ke database.
  • Setelah berhasil, memanggil fetchTodos() lagi agar UI langsung menampilkan data terbaru.

5. toggleDone()

Future<void> toggleDone(TodoModel todo) async {
  try {
    await _service.toggleDone(todo.id, todo.isDone);
    await fetchTodos(); // Refresh daftar setelah update
  } catch (e) {
    emit(state);
    rethrow;
  }
}
  • Mengubah status is_done todo (selesai/belum).
  • Setelah perubahan, memanggil fetchTodos() agar UI otomatis ter-update.

6. deleteTodo()

Future<void> deleteTodo(String id) async {
  try {
    await _service.deleteTodo(id);
    await fetchTodos(); // Refresh daftar setelah delete
  } catch (e) {
    emit(state);
    rethrow;
  }
}
  • Menghapus todo berdasarkan id.
  • Setelah berhasil, fetch ulang agar UI menampilkan data terbaru.

Kesimpulan

Pada tutorial kali ini kita sudah belajar bagaimana cara membuat state management menggunakan BLoC dengan Cubit, langkah selanjutnya kita akan membuat tampilan untuk menampilkan data dari database Supabase.

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


Faisal Mahadi
Mobile Apps Developer | Android Enthusiast | Keep Learning | Android Dev Serta Owner Hariankoding.com

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami