I'm trying to learn Riverpod with clean architecture.
I have following set/chain of providers:
final databaseFutureProvider = FutureProvider<Database>((ref) async {
final db = await DatabaseHelper().createDatabase(); // this is async because 'openDatabase' of sqflite is async
return db;
});
final toDoDatasourceProvider = Provider<ToDoDatasource>((ref) {
final db = ref.watch(databaseFutureProvider); // problem is here!!
return ToDoDatasourceImpl(db: db);
});
final toDoRepositoryProvider = Provider<ToDoRepository>((ref) {
final ds = ref.watch(toDoDatasourceProvider);
return ToDoRepositoryImpl(ds);
});
I am probably missing some small things or doing it completely wrong. How to properly provide DB (that is async in its nature)?
CodePudding user response:
You don't need multiple providers, in your case since you would need ToDoRepository
always you can just Initialized before running the app and use it later without worrying about the database connection state
Future<void> main(List<String> args) async {
// Initialization the db
final db = await DatabaseHelper().createDatabase();
ProviderScope(
overrides: [
// pass the db
toDoRepositoryProvider.overrideWithValue(db),
],
child: RootApp(),
);
}
final toDoRepositoryProvider = Provider<ToDoRepository>((ref) {
throw UnimplementedError();
});
CodePudding user response:
I totally agree with Mohammed Alfateh's decision. In addition, you can use ProviderContainer()..read(toDoDatasourceProvider)
and UncontrolledProviderScope
, to asynchronously assign values in main
method. And in ToDoDatasourceImpl
call the async method init() to assign a value in the field late final db
.