I am learning about initializing the Provider used by Riverpod on this site.
Therefore, it is explained that the following Provider initialization is old.
@Riverpod(keepAlive: true)
SharedPreferences sharedPreferences(SharedPreferencesRef ref) =>
throw UnimplementedError();
void main() async {
final sharedPreferences = await SharedPreferences.getInstance();
runApp(ProviderScope(
overrides: [
sharedPreferencesProvider.overrideWithValue(sharedPreferences)
],
child: const MainApp(),
));
}
The reason is, we should not initialize dependencies inside main as we can’t recover if something goes wrong.
But I don’t understand this. What does that mean? Why can’t main recover if something goes wrong?
2
Answers
Start by reading the previous chapter "Eager Provider Initialization with a Child Widget". The whole point is that we can handle an unsuccessful initialization by showing an error widget and a fix button (the usual
ref.invalidate()
is used there).If something goes wrong in the
main
function, you can affect it (e.g. via try-catch), but you can’t show it to the user.This is why it is recommended to use async initialization inside
FutureProvider
and further get the value viaref.watch(futureProvider).requireValue
if necessary. Or use another asynchronous provider with a dependency on this (and many others) one and handle all states viawhen
inside the widget.try this way