I'm new to GetX flutter state management. I'm using two controllers, one for Login and other for Home data(fetching some restaurants data through API call). I'm having trouble in bindings. I'm using bindings in my app following GetX docs. But I'm unable to use it properly and getting error. Following is the code -:
main.dart
void main() async {
await GetStorage.init('My Storage');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flunkey Task',
getPages: [
GetPage(
name: '/',
page: () => LandingPage(),
binding: BindingsBuilder(() {
Get.lazyPut<LoginController>(() => LoginController());
})),
GetPage(
name: '/login',
page: () => LoginScreen(),
binding: BindingsBuilder(() {
Get.lazyPut<LoginController>(() => LoginController());
})),
GetPage(
name: '/home',
page: () => HomeScreen(),
binding: BindingsBuilder(() {
Get.lazyPut<HomeController>(() => HomeController());
}),
)
],
initialRoute: '/',
);
}
}
class LandingPage extends StatelessWidget {
LandingPage({Key? key}) : super(key: key);
final _controller = Get.find<LoginController>();
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Obx(() =>
_controller.isLoggedIn.value == true ? HomeScreen() : LoginScreen());
}
}
loginController.dart
class LoginController extends GetxController {
final box = GetStorage('My Storage');
var isLoggedIn = false.obs;
final formKey = GlobalKey<FormState>();
final usernameTED = TextEditingController();
final passwordTED = TextEditingController();
@override
void onInit() {
isLoggedIn(loginStatus);
super.onInit();
}
@override
void onClose() {
usernameTED.dispose();
passwordTED.dispose();
super.onClose();
}
String? checkUsername(String username) {
if (username.isEmpty || username.length < 3 || username.length > 11) {
return 'Username must have 3-11 characters';
}
return null;
}
String? checkPassword(String password) {
if (password.isEmpty || password.length < 3 || password.length > 11) {
return 'Password must have 3-11 characters';
}
return null;
}
Future<void> login() async {
if (!formKey.currentState!.validate()) {
return;
}
if ((usernameTED.text.trim() == 'flunkey' &&
passwordTED.text.trim() == 'password123') ||
(usernameTED.text.trim() == 'user' &&
passwordTED.text.trim() == 'password123')) {
formKey.currentState!.save();
await changeLoginStatus(true);
await saveUserName(usernameTED.text);
usernameTED.clear();
passwordTED.clear();
} else {
Get.snackbar('Login Error', 'User does not exists',
backgroundColor: Colors.red[400]);
}
}
void signOut() async {
await changeLoginStatus(false);
}
Future<void> changeLoginStatus(bool status) async {
await box.write('status', status);
isLoggedIn(status);
}
Future<void> saveUserName(String name) async {
await box.write('name', name);
}
bool get loginStatus => box.read('status') ?? false;
String get currentUserName => box.read('name') ?? '';
}
homeController.dart
class HomeController extends GetxController {
final _isLoading = false.obs;
final _restaurantData = <restau.Datum>[].obs;
@override
void onInit() {
getData();
super.onInit();
}
bool get isLoading => _isLoading.value;
List<restau.Datum> get getRestaurants => _restaurantData;
Future<void> getData() async {
try {
_isLoading(true);
var apiData = await RestaurantDataApiCall.getRestaurantData();
_restaurantData.value = apiData!.data.data;
_isLoading(false);
} catch (e, s) {
print(e);
print(s);
}
}
}
Following is the error I'm getting.
I'm using Get.find() on Login Screen and Get.find() on Home screen as following,
Please guide me how to properly use Bindings in GetX.
CodePudding user response:
I don't like to bind the controllers on route. I create a MainBind.dart and put inside this class all getx controllers.
class MainBinding implements Bindings {
@override
Future<void> dependencies() async{
Get.lazyPut<AppController>(() => AppController(), fenix: true);
}
}
And in my Main.dart :
void main() async{
WidgetsFlutterBinding.ensureInitialized();
MainBinding mainBinding = MainBinding();
await mainBinding.dependencies();
runApp(const MyApp());
}
In this way I'm sure that Controllers are binded. But you can try use Put insted lazyPut too..