State Managementbeginner
GetX Controller Template
Production-ready GetX controller with reactive state, lifecycle hooks, and dependency injection.
#getx#state-management#reactive
dart
| 1 | import 'package:get/get.dart'; |
| 2 | |
| 3 | class ProductController extends GetxController { |
| 4 | // Reactive state |
| 5 | final products = <Product>[].obs; |
| 6 | final isLoading = false.obs; |
| 7 | final error = ''.obs; |
| 8 | final selectedProduct = Rxn<Product>(); |
| 9 | |
| 10 | // Dependencies |
| 11 | late final ProductRepository _repository; |
| 12 | |
| 13 | @override |
| 14 | void onInit() { |
| 15 | super.onInit(); |
| 16 | _repository = Get.find<ProductRepository>(); |
| 17 | fetchProducts(); |
| 18 | } |
| 19 | |
| 20 | @override |
| 21 | void onClose() { |
| 22 | // Cleanup subscriptions, timers etc. |
| 23 | super.onClose(); |
| 24 | } |
| 25 | |
| 26 | Future<void> fetchProducts() async { |
| 27 | isLoading.value = true; |
| 28 | error.value = ''; |
| 29 | try { |
| 30 | products.value = await _repository.getProducts(); |
| 31 | } catch (e) { |
| 32 | error.value = e.toString(); |
| 33 | } finally { |
| 34 | isLoading.value = false; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | void selectProduct(Product product) { |
| 39 | selectedProduct.value = product; |
| 40 | } |
| 41 | |
| 42 | void clearSelection() => selectedProduct.value = null; |
| 43 | } |
| 44 | |
| 45 | // Usage in widget |
| 46 | class ProductsPage extends GetView<ProductController> { |
| 47 | const ProductsPage({super.key}); |
| 48 | |
| 49 | @override |
| 50 | Widget build(BuildContext context) { |
| 51 | return Scaffold( |
| 52 | body: Obx(() { |
| 53 | if (controller.isLoading.value) return const Center(child: CircularProgressIndicator()); |
| 54 | if (controller.error.value.isNotEmpty) return Center(child: Text(controller.error.value)); |
| 55 | return ListView.builder( |
| 56 | itemCount: controller.products.length, |
| 57 | itemBuilder: (_, i) => ListTile(title: Text(controller.products[i].name)), |
| 58 | ); |
| 59 | }), |
| 60 | ); |
| 61 | } |
| 62 | } |