Search code examples
flutterwebflutter-getx

Flutter GetX Refreshing Explorer restart controllers


I'm using GetX for state management in a Flutter web application. I have created an authcontroller with a login method. When I call the method anywhere in the application it works and the UI changes with the new state. But when I refresh explorer the controller is reset and login state is lost.

I have created a small version of the code easy to reproduce:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp( MyApp());
}

class MyApp extends StatelessWidget {
  AuthController authController = Get.put(AuthController(), permanent: true);
  MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      smartManagement: SmartManagement.keepFactory,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}


class HomeScreen extends StatelessWidget {
  HomeScreen({Key? key}) : super(key: key);
  final AuthController authController = Get.find();

  @override
  Widget build(BuildContext context) {
    return Center(
        child: ElevatedButton(
          child: Obx(() => authController.isAuthenticated.value ? Text("authenticated") : Text("authenticate")),
          onPressed: () {
            authController.login();
          },
        )
    );
  }
}


class AuthController extends GetxController {
  var isAuthenticated = false.obs;

  void login() {
    isAuthenticated.value = true;
    update();
  }
}

As you can see I'm using the permanent:true prop but the controller still is re-initialized.

This is how the issue looks:

enter image description here

Is there any prop or config that I'm missing? how to avoid this behavior?


Solution

  • The error in your code is that the Controller is recreated every time the page is refreshed. That is why Use GetStorage package.

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    void main() async {
      await GetStorage.init(); // Add this first
      runApp( MyApp());
    }
    
    class MyApp extends StatelessWidget {
      AuthController authController = Get.put(AuthController(), permanent: true);
      MyApp({Key? key}) : super(key: key);
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          title: 'Flutter Demo',
          smartManagement: SmartManagement.keepFactory,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: HomeScreen(),
        );
      }
    }
    
    
    class HomeScreen extends StatelessWidget {
      HomeScreen({Key? key}) : super(key: key);
      final AuthController authController = Get.find();
    
      @override
      Widget build(BuildContext context) {
        return Center(
            child: ElevatedButton(
              child:  _isLoged.read('login') == false || 
                      _isLoged.read('login') == null ? Text("authenticate") 
                      : Text("authenticated")  ,
              onPressed: () {
                authController.login();
              },
            )
        );
      }
    }
    
    
    class AuthController extends GetxController {
      var _isLoged = GetStorage(); // In the controller, it is necessary to save the entry with this
       
    
      void login() async {
        await _isLoged.write('login', true);
        update();
         
      }
    }