Modal Bottom Sheet and Bloc

Viewed 4225

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')
          );
    },
  );
}
2 Answers

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( ...
     ...

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)

Related