Last active
September 24, 2021 17:19
-
-
Save manikantag/18a0cab5ea2423e321aae62e50a3e00d to your computer and use it in GitHub Desktop.
Flutter Getx observable assignment in async issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| import 'package:get/get.dart'; | |
| void main() async { | |
| WidgetsFlutterBinding.ensureInitialized(); | |
| runApp(GetMaterialApp.router( | |
| title: 'Test', | |
| initialBinding: BindingsBuilder.put(() => AuthService(), permanent: true), | |
| getPages: [ | |
| GetPage( | |
| name: '/', | |
| page: () => const LoginScreen(), | |
| binding: BindingsBuilder.put(() => LoginController()), | |
| ), | |
| GetPage( | |
| name: '/home', | |
| page: () => const HomeScreen(), | |
| binding: BindingsBuilder.put(() => HomeController()), | |
| ), | |
| ], | |
| )); | |
| } | |
| class AppUser { | |
| final String uid; | |
| final String mobile; | |
| int count = 0; | |
| AppUser({required this.uid, required this.mobile}); | |
| AppUser.newUser(String uid, String mobile) : this(uid: uid, mobile: mobile); | |
| AppUser.dummyUser() : this(uid: '', mobile: ''); | |
| @override | |
| String toString() { | |
| return {'mobile': mobile, 'uid': uid, 'counter': count}.toString(); | |
| } | |
| } | |
| // ----- models ----- | |
| class Doctor extends AppUser { | |
| final String? regId; | |
| Doctor({required String uid, required String mobile, this.regId}) | |
| : super(uid: uid, mobile: mobile); | |
| Doctor.newDoctor(String uid, String mobile) : this(mobile: mobile, uid: uid); | |
| } | |
| class Patient extends AppUser { | |
| final String? bmi; | |
| Patient({required String uid, required String mobile, this.bmi}) | |
| : super(uid: uid, mobile: mobile); | |
| Patient.newPatient(String uid, String mobile) : this(uid: uid, mobile: mobile); | |
| } | |
| // ----- Auth service ----- | |
| class AuthService extends GetxController { | |
| Rx<bool> isAuthenticated = false.obs; | |
| Rx<int> authCounter = 0.obs; | |
| Rx<AppUser> currentUser = Rx(AppUser.dummyUser()); | |
| /* @override | |
| void onInit() { | |
| currentUser = Patient.newPatient('patient1', 'patientm1').toRx(); | |
| super.onInit(); | |
| } */ | |
| void doPatientLogin() async { | |
| isAuthenticated.value = true; | |
| // currentUser = Patient.newPatient('Patient_1', 'Patient_mobile_1').toRx(); | |
| currentUser = await Future.delayed( | |
| const Duration(milliseconds: 10), | |
| () => Patient.newPatient('Patient_1', 'Patient_mobile_1').obs, | |
| ); | |
| print(currentUser); | |
| } | |
| void doDoctorLogin() async { | |
| isAuthenticated.value = true; | |
| // currentUser = Doctor.newDoctor('Doc_1', 'Doc_mobile_1').toRx(); | |
| currentUser = await Future.delayed( | |
| const Duration(milliseconds: 10), | |
| () => Doctor.newDoctor('Doc_1', 'Doc_mobile_1').obs, | |
| ); | |
| print(currentUser); | |
| } | |
| void doLogout() { | |
| isAuthenticated.value = false; | |
| authCounter = 0.obs; | |
| // tempCounter = Patient.newPatient('p2', 'm2').toRx(); | |
| // currentUser = Doctor.newDoctor('doctor1', 'docm1').toRx(); | |
| Get.rootDelegate.offNamed('/'); | |
| // Get.reset(); | |
| // Get.reloadAll(force: true); | |
| // Get.reload<AuthService>(); | |
| // Get.deleteAll(force: true); | |
| } | |
| } | |
| // ----- Login controller & page ----- | |
| class LoginController extends GetxController { | |
| final authService = Get.find<AuthService>(); | |
| bool isLoggedin() => authService.isAuthenticated.value == true; | |
| void doDoctorLogin() { | |
| authService.doDoctorLogin(); | |
| Get.rootDelegate.offNamed('/home'); | |
| } | |
| void doPatientLogin() { | |
| authService.doPatientLogin(); | |
| Get.rootDelegate.offNamed('/home'); | |
| } | |
| } | |
| class LoginScreen extends GetView<LoginController> { | |
| const LoginScreen({Key? key}) : super(key: key); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Center( | |
| child: Obx( | |
| () => controller.isLoggedin() | |
| ? const Text('Already logged in -> Logout (state not cleared)') | |
| : Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: [ | |
| Text('authCounter: ${controller.authService.authCounter.value}'), | |
| ElevatedButton( | |
| onPressed: controller.doDoctorLogin, | |
| child: const Text('Doctor Login'), | |
| ), | |
| ElevatedButton( | |
| onPressed: controller.doPatientLogin, | |
| child: const Text('Patient Login'), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| // ----- Home controller & page ----- | |
| class HomeController extends GetxController { | |
| final AuthService _authService = Get.find<AuthService>(); | |
| final Rx<int> homeCounter = 0.obs; | |
| late final Rx<int> authCounter; | |
| late final Rx<AppUser> currentUser; | |
| @override | |
| void onInit() { | |
| authCounter = _authService.authCounter; | |
| currentUser = _authService.currentUser; | |
| super.onInit(); | |
| } | |
| void increment() { | |
| homeCounter.value++; | |
| authCounter.value++; | |
| currentUser.value.count++; | |
| } | |
| void logout() => _authService.doLogout(); | |
| } | |
| class HomeScreen extends GetView<HomeController> { | |
| const HomeScreen({Key? key}) : super(key: key); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Obx( | |
| () => Center( | |
| child: Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: [ | |
| Text('Auth counter: ${controller.authCounter.value}'), | |
| Text('Home counter: ${controller.homeCounter.value}'), | |
| Text( | |
| 'Current User: ${controller.currentUser.value is Doctor ? 'Doctor' : 'Patient'}'), | |
| Text('Current User: ${controller.currentUser.value}'), | |
| ElevatedButton( | |
| onPressed: controller.increment, | |
| child: const Text('Increment counters'), | |
| ), | |
| ElevatedButton( | |
| onPressed: controller.logout, | |
| child: const Text('Logout'), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fix is to add
awaitat line 112 & 117.