One of my services, UserService
, has an async init
method (as it calls Hive.openBox
).
I need this initialization to complete in order to inject this dependency into ChatService
.
main() {
runApp(MultiProvider(
providers: [
Provider<Api>.value(value: Api()),
ProxyProvider<Api, UserService>(update: (_, api, __) async {
var service = UserService(api);
await service.init();
return service;
}),
ChangeNotifierProxyProvider<UserService, ChatService>(
create: (_) => ChatService(),
update: (_, userService, chatService) => chatService..userService = userService
),
],
child: MyApp(),
));
}
Of course, attempting to make create async
gives the following error because of the type mismatch:
The argument type 'Future<UserService> Function(BuildContext, Api, UserService)' can't be assigned to the parameter type 'UserService Function(BuildContext, Api, UserService)'.dart(argument_type_not_assignable)
How can I await this method using ProxyProvider
?
Is get_it
a better tool for what I'm trying to do?
EDIT AFTER REMI'S ANSWER
I'm using FutureProvider
now but it's still unclear how to feed the initialized UserService
dependency into the next dependant ChatService
when it's immutable:
providers: [
Provider<Api>(create: (_) => Api()),
FutureProvider<UserService>(
lazy: false,
create: (context) async {
var service = UserService(Provider.of(context, listen: false));
await service.init();
return service;
}
),
ChangeNotifierProvider<ChatService>(
create: (context) => ChatService(Provider.of<UserService>(context, listen: false)), // UserService is null
)
],
UserService
is null
by the time create
is called.
Using a ChangeNotifierProxyProvider
's update
that wouldn't work either UserService
is a constructor dependency.
You can use FutureProvider
instead:
Provider<Api>(create: (_) => Api()),
FutureProvider<UserService>(
create: (context) async {
var service = UserService(Provider.of(context, listen: false));
await service.init();
return service;
},
),
You could also do:
void main() async {
final service = UserService();
await service.init();
runApp(
Provider.value(
value: service,
),
);
}