Modal Bottom Sheet and Bloc
Asked Answered
P

2

11

I get the following error when I run code similar to the below code: BlocProvider.of() called with a context that does not contain a Bloc.

To replicate

BlocProvider(
          create: (context) => getIt<TheBloc>()
          child: BlocBuilder<TheBloc, TheState>(
          build: (context, state) =>
          MaterialButton(
            onPressed: () => _showModal(context),
            child: const Text('SHOW BLOC MODAL'),
),

...

void _showModal(BuildContext context) {
  showModalBottomSheet<void>(
    context: context,
    builder: (_) {
          return MaterialButton(
               onPressed() {
                       context.bloc<TheBloc>().add(
                         TheEvent.someEvent(),
                       );
               }
              child: Text('Press button to add event to bloc')
          );
    },
  );
}
Pantia answered 29/6, 2020 at 12:5 Comment(2)
I reviewed you snippets - this example should work. I guess reason somewhere in you real codeFustigate
@SergeySalnikov the issue was this code, I fixed it by wrapping the builder of the modal in a BlocProvider.value as per the bloc api reference. I've added the answer to the question. ThanksPantia
P
20

You need to wrap the builder of showModalBottomSheet with a BlocProvider.value as follows: As the context is new.

return BlocProvider.value(
     value: BlocProvider.of<TheBloc>(context),
     child: MaterialButton( ...
     ...
Pantia answered 1/7, 2020 at 1:31 Comment(2)
It will more clear if you pass bloc to _showModal(TheBloc bloc) and skip unnessesssary lookup in context =)Fustigate
can u please explain it little bit moreDentelle
S
2

Actually if you need this bloc only in bottom sheet and nowhere else, the better and cleaner solution is create the StatefullWidget for bottom sheet content, create the Bloc inside this widget in initState() work with bloc in build() method and free resources in dispose() method.

  showModalBottomSheet<void>(
    context: context,
    builder: (_) {
          return MyBottomSheet(); // your stateful widget
        );
    },
  );

Using bloc like above guarantee that state of your bloc will be the same on each showModalBottomSheet call

Note. If you need to preserve state of bloc, you can try to use AutomaticKeepAliveClientMixin (did not tested)

Splanchnic answered 12/2, 2022 at 8:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.