Can't access bloc in showModal context in Flutter

Issue

I wrap my scafflod with dart BlocProvider<ABloc,AState>
but when I use showDialog func and showDialog I want to access ABloc from context or BlocBuilder
doesn’t contain bloc and throw error
is there a way to access bloc in this situatuion
(in my dialog I show text filed to get user name so I want to access bloc)

class MyHomePageState extends StateLessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
        lazy: false,
        create: (context) => EditColorBloc(context.bloc<RetrieveColorBloc>()),
        child: MainScafold());
  }
}
class MainScafold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("sina"),
      ),
      floatingActionButton:FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () => showDialog(
              context: context,
              builder: (ctx) {
              // show dialog and use 
              // context o BlocBuilder to access 
              // EditColorBloc
              // throw error BlocProvider.of() called with a context that does 
              // not contain a Cubit of type EditColorBloc
              }
           )
  }
}

Solution

UPDATE v6.1.0

(Credit to @Sebastian Dennis)

context.bloc was deprecated in favor of provider’s context.read, context.watch, and context.select. In the below code, just change context.bloc<TestBloc> to context.read<TestBloc>


You shouldn’t use a BlocBuilder to wrap the Dialog. Reason being is that you’re (most likely) not rebuilding the whole Dialog whenever a change occurs. Another, more important, reason is that the context in which your Dialog is being built doesn’t contain your bloc, so you need to inject your bloc instance into the Dialog‘s context.

Instead, use BlocProvider.value and set the value parameter to BlocProvider.of(context) (aka context.bloc() ), and make sure the context is not the showDailog ‘s method context, but the context in the original build method.

Here is a working example. You just have to change the TestBloc or TestState etc to your own Bloc instances:

  @override
  Widget build(BuildContext context) {
    return BlocProvider<TestBloc>(
        create: (context) => TestBloc(InitTestState()),
        child: Scaffold(
            body: BlocBuilder<TestBloc, TestState>(
              builder: (context, state) => Center(
                child: FlatButton(
                  child: Text("Show Dialog"), 
                  onPressed: () => showDialog(
                      context: context, 

                      // Relavent code change here
                      builder: (ctx) => BlocProvider<TestBloc>.value(
                        value: context.bloc<TestBloc>(), 

                        child: Dialog(
                          child: FlatButton(
                            child: Text("Notify bloc"),
                            onPressed: () => context
                                .bloc<TestBloc>()
                                .add(TestEvent()),
                          ),
                        ),
                      )),
            ),
          ),
        )));

Answered By – hman_codes

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *