Why Choose Riverpod? - ProviderScope

Why Choose Riverpod? - ProviderScope

This post is based off a presentation I did at Devfest 2023 in Cape Town on 23 Nov 2023. VIDEO | PRESENTATION


In the last post we took a look at accessing our provider, this time we are going to take at the secret sauce


is a wrapper widget provided by Riverpod and it is what providers a lot of the secret sauce, ProviderScope in the simplest of use cases wraps your main widget inside runApp. This is how Riverpod ensures that all the providers are accessible app wide.

void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

However it does also provide the ability to override providers, at this point the most likely reasons for that would be to setup providers that rely on things that need to startup first.

One such example from our project would be the Google Places SDK, while it itself does not need any startup time, our application makes use of flavours to allow for building against multiple environments, so at build time we need to pull out the specific API key for things like the Google Places SDK.

// core_providers.dart
final googlePlacesSdkProvider = Provider<FlutterGooglePlacesSdk>(
  (_) => throw UnimplementedError("FlutterGooglePlacesSdk not implemented"),
);

void main() async {
  await F.getFlavor();
  await F.loadEnv();

  runApp(
    ProviderScope(
    Overrides: [
      googlePlacesSdkProvider.overrideWith(
          (_) => FlutterGooglePlacesSdk(F.googlePlacesApiKey),
        ),
      ],
      child: MyApp(),
    ),
  );
}

in out core_providers.dart file we have setup a provider with a type of FlutterGooglePlacesSdk, which as you will see simply throws Unimplemented, and this is so that we can setup this provider for the purpose of being able to override it within the ProviderScope widget during startup.

Once the API keys are loading up by F.loadEnv(), we can simply use the overrideWith method available to all Riverpod providers to bring in the FlutterGooglePlacesSdk with the correct API key from the now loaded environment variables.

This though is just one pretty simple, bur probably more common use case, and within our application we use the same pattern for SharedPreferences and Firebase, registering these with providers makes accessing them far simpler throughout the application as we would then be able to directly access them both within the UI and within the business logic classes.

Reasoning will also make much more sense in the next section when we start looking into testing.


In the last post we are going to take a look at how Riverpod can simplify our lives with testing.


I hope you found this interesting, and if you have any questions, comments, or improvements, feel free to drop a comment. Enjoy your development journey :D

Thanks for reading.