Flutter ждет, когда провайдер будет готов внутри мультипровайдера
У меня проблема с синхронизацией создания провайдеров. Я новичок в флаттере, постараюсь объяснить получше, как смогу.
В моем main.dart у меня есть два провайдера: один для авторизации пользователя и один для другого виджета в коде, у него просто есть список для отображения. Я использую ChangeNotifierProxyProvider, потому что все остальные провайдеры должны иметь доступ к токенам аутентификации и деталям пользователей. Все методы для хранения и чтения токенов находятся в userProvider.
Когда вызывается UserProvder.init(), объект создается, но все еще не готов из-за HTTP-запроса, код в основном продолжает выполняться и передает UserProvider поставщику Conto, который считает, что UserProvider готов, но это не так. Когда ContoProvider начинает извлекать список с токеном внутри UserProvider, доступ через userService завершается неудачно, поскольку все еще имеет значение null.
Итак, как мне синхронизировать создание провайдера, чтобы дождаться полной готовности 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 ответ
Вы можете использовать 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 к внешним / веб-ресурсам. Вы можете передать такой класс своему провайдеру в качестве аргументов.