2
// main.dart
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<LoginProvider>(create: (_) => LoginProvider()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        routes: {
          '/' : (context) => LoginPage(),
          MainPage.routeName : (context) => MainPage(),
          RecipePage.routeName : (context) => RecipePage(),
          FoodPage.routeName : (context) => FoodPage(),
          LoginPage.routeName : (context) => LoginPage()
        },
      )
    );
  }
}
// login_provider.dart
class LoginProvider with ChangeNotifier {
  static const String KEY_IS_LOGIN = "IS_LOGIN";
  static const String KEY_USER_ID = "USER_ID";

  User _me;
  bool _isLogin;

  LoginProvider() {
    setup();
  }

  void setup() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _isLogin = prefs.getBool(KEY_IS_LOGIN) ?? false;

    if(_isLogin) {
      String uid = prefs.getString(KEY_USER_ID);
      if(uid == null) {
        prefs.setBool(KEY_IS_LOGIN, false);
      } else {
        User user = await DBHelper.getUser(uid);
        
        if(user == null) {
          prefs.setBool(KEY_IS_LOGIN, false);
        } else {
          _me = user;
        }
      }
    }
  }

  bool get isLogin => _isLogin;

  void setLogin(String id) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool(KEY_IS_LOGIN, true);
    prefs.setString(KEY_USER_ID, id);
  }

  User get me => _me;

  set me(User value) {
    _me = value;
    notifyListeners();
  }
}
// parts of DBHelper(db_helper.dart)
static Future<User> getUser(String uid) async {
  http.Response response = await http.get('http://$IP:3000/user/$uid');
  if(response.body == '{}') return null;
  return User.fromJsonString(response.body);
}

I have to get data from server when the app is start.

In MultiProvider, I called LoginProvider's constructor.

And In LoginProvider's constructor, I called setup function that load user data from server if user id which is in SharedPreferences is valid. (if user id is invalid, set isLogin false.)

So, My app has to wait until user data is completely load.

Can someone help me?

Thanks.

1 Answer 1

4

You have 2 options:

1 - Create splash page and call, await setup from there and navigate to login page afterwards.

2 - Call and await setup from login page. Until the method is finished you need to show some loading widget.

You need to change setup to Future<void> so we can await for the method, and call it from login page / splash page and not from the constructor.

  Future<void> setup() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _isLogin = prefs.getBool(KEY_IS_LOGIN) ?? false;

    if(_isLogin) {
      String uid = prefs.getString(KEY_USER_ID);
      if(uid == null) {
        prefs.setBool(KEY_IS_LOGIN, false);
      } else {
        User user = await DBHelper.getUser(uid);
        
        if(user == null) {
          prefs.setBool(KEY_IS_LOGIN, false);
        } else {
          _me = user;
        }
      }
    }

  }

Either login/splash page options you need a method that looks like this:

initState() {
super.initState();
// set initial loading widgets
loadDataFromModel();
}

void loadDataFromModel() async {
await Provider.of<LoginProvider>.setup();
setState(() {
// set your login widgets after the model fetched data
}) 
}

Or you can use alternative FutureBuilder (attached setup future to the builder and handle connection state)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I solved it: await Provider.of<LoginProvider>(context, listen: false).setup();
Thank you guys, you saved me hours of troubleshooting

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.