skip to Main Content

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


  1. 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 via ref.watch(futureProvider).requireValue if necessary. Or use another asynchronous provider with a dependency on this (and many others) one and handle all states via when inside the widget.

    Login or Signup to reply.
  2. try this way

    void main() async {  
      try {
        final sharedPreferences = await SharedPreferences.getInstance();
        runApp(ProviderScope(
          overrides: [
            sharedPreferencesProvider.overrideWithValue(sharedPreferences)
          ],
          child: const MainApp(),
        ));
      } catch (error) {
        print('Error during initialization: $error');
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search