How to access Provider providers in Dialogs in Flutter

JustLearningAgain picture JustLearningAgain · Sep 17, 2019 · Viewed 7.2k times · Source

The Provider package makes use of InheritedWidget. This is a problem when I want to access a provider when I'm in a Dialog. If I load a dialog using

 showDialog(... builder: (context) => MyDialog);

I can't access anything using InheritedWidget because my dialog isn't part of the main widget tree. This also means that I can't access my Provider providers, correct?

My question is: How can I access my providers in a dialog if it's not part of the main app widget tree?

final firebaseAuth = Provider.of<FirebaseAuth>(context);

I have the same problem with using BLoCs. If I try to retrieve them in a dialog via InheritedWidget, they fail. I've gotten around this by passing the BLoC in the constructor but this seems to defeat the purpose of InheritedWidgets.

Answer

SteveM picture SteveM · Jun 17, 2020

Instead of passing the BLoC in the constructor, you can make use of BlocProvider.value.

https://pub.dev/documentation/flutter_bloc/latest/flutter_bloc/BlocProvider/BlocProvider.value.html

This will allow you to provide your existing BLoC instance to your new route (the dialog). And you still get all the benefits of InheritedWidget

  // Get the BLoC using the provider
  MyBloc myBloc = BlocProvider.of<MyBloc>(context);

  showDialog(
    context: context,
    builder: (BuildContext context) {
      Widget dialog = SimpleDialog(
        children: <Widget>[
          ... // Now you can call BlocProvider.of<MyBloc>(context); and it will work
        ],
      );

      // Provide the existing BLoC instance to the new route (the dialog)
      return BlocProvider<MyBloc>.value(
        value: myBloc, //
        child: dialog,
      );
    },
  );

.value() also exists for ChangeNotifierProvider, ListenableProvider, etc. https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider/ChangeNotifierProvider.value.html

https://pub.dev/documentation/provider/latest/provider/ListenableProvider/ListenableProvider.value.html