简体   繁体   中英

Flutter await Provider to be ready inside multiprovider

I have a problem with synchronize Providers creation. I'm new to flutter, I'll try to explain better as i can.

In my main.dart i have two providers one for the user auth and one for another widget into the code, it simply have a list to display. I use ChangeNotifierProxyProvider because all other provider needs to access to user auth tokens and details. All methods for user to store,read tokens are in the userProvider.

When UserProvder.init() is called the object is created but is still not ready beacuse of the http request, the code in the main continue to execute and pass the UserProvider to the Conto Provider that thinks UserProvider is ready but it is not. When the ContoProvider start to retrive the List with the token inside UserProvider access through userService failed the call because is still null.

So, How can i synchronize the creation of provider in order to wait the UserProvider to be full ready and then initialize all other providers?

main.dart

Widget build(BuildContext context) {
return MultiProvider(
  providers: [
    ChangeNotifierProvider<UserProvider>(
      create:  (_)  => UserProvider.init(),

    ),
    ChangeNotifierProxyProvider<UserProvider, ContoProvider>(
      create: (_) {
        return ContoProvider.init(
            Provider.of<UserProvider>(_, listen: false));
        },

      update: (_,  userProvider,  contoProvider) =>
          contoProvider..update(userProvider),
    ),
  ],
  child:... 

userProvider.dart

      User activeUser = User(null, null, null);
      UserStatus status = UserStatus.Checking;


        UserProvider.init() {

            checkUserPresence();
          }

          void checkUserPresence() async {
             /*here i check if in secure storage there is a refreshtoken if there is i make an http
 request for a new token and a second request to fill the User into UserProvider so i need await async*/
          }

ContoProvider.dart

    UserProvider userService;
      ContoProvider.init(UserProvider user) {

        userService = user;

        lookUpConti();
      }

      void lookUpConti() async {
        /*here i make an http call to retrive some data, i access to 
userService for get token and refresh token if needed*/
    }

You can use WidgetsFlutterBinding.ensureInitialized()

void main() {

  /** WidgetsFlutterBinding.ensureInitialized() is required in Flutter v1.9.4+ before using any plugins if the code is executed before runApp. */

  WidgetsFlutterBinding.ensureInitialized();



  runApp(
    MultiProvider(
      providers: [
         ChangeNotifierProvider<UserProvider>(
           create:  (_)  => UserProvider.init()),

         ChangeNotifierProxyProvider<UserProvider, ContoProvider>(
            create: (_) {
               return ContoProvider.init(
                   Provider.of<UserProvider>(_, listen: false));
             },

           update: (_,  userProvider,  contoProvider) =>
             contoProvider..update(userProvider),
         ),
       ],
      child: MyApp(),
    ),

}

PS : I will recommend that you separate your repositories from your provider. That is, not API call to external/web resources should be found in your provider. You can pass such class into your provider as arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM