Search code examples
flutterdartrealm

Global value is not initalized


I have a global variable User? current_atlas_user that is in file 'Constants.dart'. I want to initialize it from the main.dart file. To do it I am trying this:

Future<void> setAtlasUser(String email) async {
  final app = App(AppConfiguration(APP_ID));
  current_atlas_user =
      await app.logIn(Credentials.emailPassword(email, ATLAS_PASSWD));
}

This function is called in the end of the @override void initState() function. And after using the debugger I made sure that the code is reaching the Future<void> setAtlasUser(String email) function.

My problem is here

  @override
  Widget build(BuildContext context) {
    List<Widget> _screens = [NotDoneScreen(), const DoneScreen()];

The NotDoneScreen() assumes that current_atlas_user is already defined. But when running the code it fails saying that it is still null.

I know that initState() should run before build() and therefore I am confused about this problem.


Solution

  • You can use FutureBuilder to wait for current_atlas_user to initialize. While waiting for future to finish, you can show some sort of loading indicator. Here is how I would structure it:

    1. create a local variable to store the future:
    Future<void>? _current_atlas_user_future;
    
    1. assign value to local variable in initState
    @override
      void initState() {
        super.initState();
        _current_atlas_user_future = setAtlasUser(email);
      }
    
    1. now add FutureBuilder to build method
    
    @override
      Widget build(BuildContext context) {
        return FutureBuilder<void>(
           future: _current_atlas_user_future,
            builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                     // current_atlas_user should be ready here
                     // load the screens
                     List<Widget> _screens = [NotDoneScreen(), const DoneScreen()];
    
                } else {
                     // current_atlas_user should be null here
    
                    // show some sort of loading indicator
                    return CircularProgressIndicator();
                }
            }
        );
    }
    

    Note that _current_atlas_user_future is separate from current_atlas_user . _current_atlas_user_future is just holding reference to a future and current_atlas_user is the value you need in your next screen.