Флаттер ждет поставщика, который будет готов внутри мультипровайдера - PullRequest
1 голос
/ 09 марта 2020

У меня проблема с синхронизацией создания провайдеров. Я новичок в трепетании, постараюсь объяснить как можно лучше.

В моем main.dart у меня есть два провайдера, один для аутентификации пользователя и один для другого виджета в коде, он просто имеет список для отображения. Я использую ChangeNotifierProxyProvider, потому что все другие поставщики должны иметь доступ к токенам и деталям аутентификации пользователя. Все методы, которые пользователь может сохранить, прочитать токены в userProvider.

Когда вызывается UserProvder.init (), объект создается, но все еще не готов из-за запроса http, код в основном продолжает выполнить и передать UserProvider поставщику Conto, который считает, что UserProvider готов, но это не так. Когда ContoProvider начинает получать список с токеном внутри доступа UserProvider через userService, произошел сбой вызова, потому что он по-прежнему равен нулю.

Итак, как я могу синхронизировать создание провайдера, чтобы дождаться, когда UserProvider будет полностью готов? а затем инициализировать всех других провайдеров?

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*/
    }

1 Ответ

1 голос
/ 01 мая 2020

Вы можете использовать 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 : я рекомендую вам отделить ваши репозитории от вашего провайдера. То есть, не вызов API для внешних / веб-ресурсов должен быть найден у вашего провайдера. Вы можете передать такой класс в ваш провайдер в качестве аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...