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)