Dalam konteks pemrograman Flutter, khususnya ketika menggunakan paket seperti freezed atau sealed_unions untuk membuat state management lebih terstruktur dan prediktif, kita sering berurusan dengan berbagai jenis state atau metode untuk menangani data state. Berikut adalah beberapa jenis state yang umum dan penjelasannya:

1. maybeMap

maybeMap digunakan untuk memetakan state yang berbeda ke fungsi yang berbeda, namun menyediakan opsi default. Ini berguna ketika Anda ingin menangani beberapa state secara spesifik, tetapi juga ingin menyediakan penanganan umum untuk state lainnya.

Contoh maybeMap

Anggap Anda memiliki UserState dengan beberapa sub-state seperti Loading, Success, dan Error. Anda ingin menangani Success dan Error secara spesifik, namun untuk semua state lainnya, Anda ingin melakukan operasi default.

@freezed
class UserState with _$UserState {
  const factory UserState.loading() = Loading;
  const factory UserState.success(User user) = Success;
  const factory UserState.error(String message) = Error;
}

// Menggunakan maybeMap
userState.maybeMap(
  success: (Success state) => print('User loaded: ${state.user}'),
  error: (Error state) => print('Error: ${state.message}'),
  orElse: () => print('Loading or another state'),
);

2. mapOrNull

Mirip dengan maybeMap, mapOrNull memungkinkan Anda memetakan state yang berbeda ke fungsi yang berbeda, tetapi mengembalikan null untuk state yang tidak di-handle. Ini berguna jika Anda hanya tertarik pada beberapa state tertentu dan ingin mengabaikan yang lain.

Contoh mapOrNull

mapOrNull memungkinkan Anda menangani beberapa state secara spesifik, dan mengembalikan null untuk state yang tidak ditangani. Ini berguna untuk kasus di mana Anda hanya tertarik pada satu atau beberapa state tertentu.

@freezed
class UserState with _$UserState {
  const factory UserState.loading() = Loading;
  const factory UserState.success(User user) = Success;
  const factory UserState.error(String message) = Error;
}

// Menggunakan mapOrNull
final userName = userState.mapOrNull(
  success: (Success state) => state.user.name,
  // State lainnya akan mengembalikan null
);

3. when

Metode when memungkinkan Anda menentukan fungsi atau aksi yang berbeda untuk setiap kemungkinan state. Ini sering digunakan dalam state management untuk menangani setiap kemungkinan state secara eksplisit.

Contoh when

when mirip dengan map tetapi menggunakan value daripada state. Anda harus menangani setiap kemungkinan state.

// Menggunakan when
userState.when(
  loading: () => print('Loading user data...'),
  success: (User user) => print('User loaded: ${user.name}'),
  error: (String message) => print('Error: $message'),
);

4. maybeWhen

Mirip dengan when, namun maybeWhen menyediakan opsi default yang akan dijalankan jika tidak ada state yang cocok dengan yang diberikan. Ini berguna untuk menyediakan penanganan umum untuk state yang tidak spesifik.

Contoh maybeWhen

Mirip dengan maybeMap, maybeWhen memungkinkan Anda untuk menangani beberapa state secara spesifik dan memberikan penanganan default untuk state lainnya.

// Menggunakan maybeWhen
userState.maybeWhen(
  success: (User user) => print('User loaded: ${user.name}'),
  error: (String message) => print('Error: $message'),
  orElse: () => print('Loading or another state'),
);

5. map

map adalah cara untuk mengubah setiap state menjadi tindakan atau objek lain. Setiap state harus dihandle, dan tidak ada opsi default seperti dalam maybeMap.

Contoh map

Dalam map, Anda harus menangani setiap kemungkinan state. Ini bermanfaat ketika Anda ingin memastikan bahwa setiap state memiliki penanganan yang spesifik.

// Menggunakan map
userState.map(
  loading: (Loading state) => print('Loading user data...'),
  success: (Success state) => print('User loaded: ${state.user}'),
  error: (Error state) => print('Error: ${state.message}'),
);

6. fold

fold adalah metode yang memungkinkan Anda menggabungkan semua kemungkinan state menjadi satu hasil. Ini biasanya memerlukan dua fungsi: satu untuk state sukses dan satu untuk state gagal atau default.

Contoh fold

fold digunakan untuk mengkondensasi state menjadi satu nilai, biasanya digunakan dalam konteks error handling atau loading state.

// Menggunakan fold
final result = userState.fold(
  () => 'Loading', // Callable jika tanpa parameter
  (state) => state is Success ? 'Success' : 'Error',
);

7. whenOrNull

Mirip dengan maybeWhen, tetapi untuk when. whenOrNull memberikan penanganan untuk beberapa state tertentu, dan mengembalikan null untuk state yang tidak dihandle.

Contoh whenOrNull

Mirip dengan when, tetapi mengembalikan null untuk state yang tidak ditangani.

// Menggunakan whenOrNull
final message = userState.whenOrNull(
  error: (String message) => message,
); // Mengembalikan pesan error, atau null jika tidak dalam state Error

8. asMap

asMap mengonversi state menjadi map, dengan kunci sebagai state dan nilai sebagai data terkait dengan state tersebut.

Contoh asMap

asMap digunakan untuk mengonversi koleksi ke bentuk Map, dengan index sebagai key.

final list = ['Apple', 'Banana', 'Cherry'];
final map = list.asMap(); // {0: 'Apple', 1: 'Banana', 2: 'Cherry'}

9. toList

toList mengonversi state menjadi list. Ini berguna jika Anda memiliki state yang mewakili koleksi item dan Anda ingin memanipulasinya sebagai list.

Contoh toList

toList digunakan untuk mengonversi koleksi lain (seperti Set atau Map) menjadi List.

final set = {'Apple', 'Banana', 'Cherry'};
final list = set.toList(); // ['Apple', 'Banana', 'Cherry']

10. whereType

whereType digunakan untuk menyaring state berdasarkan tipe data tertentu. Ini berguna dalam situasi polymorphic, di mana Anda ingin menangani hanya state tertentu yang sesuai dengan tipe data yang diberikan.

Setiap metode ini memberikan cara yang berbeda untuk berinteraksi dengan state dalam aplikasi Flutter, memungkinkan Anda untuk mengatur logika aplikasi Anda secara lebih bersih dan lebih terprediksi.

Contoh whereType

whereType digunakan untuk memfilter koleksi berdasarkan tipe data.

final mixedList = ['Hello', 1, 'World', 2, 3];
final stringList = mixedList.whereType<String>().toList(); // ['Hello', 'World']

Semoga contoh-contoh ini membantu Anda memahami penggunaan berbagai metode dalam Flutter dan Dart!