Hello,
I fow a while a old version of flutter_bloc. Today i start with flutter_bloc 3.1.0
I'm got a bug or I didn't understand something :/
This is the build method of my StatefullWidget :
@override
Widget build(BuildContext context) {
return BlocProvider<MapBloc>(
create: (context) => MapBloc(),
child: BlocListener<MapBloc, MapState>(
bloc: BlocProvider.of<MapBloc>(context),
listener: (context, MapState state) {
print("test");
},
child: Material(),
),
);
}
BlocListener use the context provided by the build method. The BlocProvider under it didn't update the context and my BlocListener didn't have access to the bloc....
BlocProvider.of() called with a context that does not contain a Bloc of type MapBloc.
Can you help me :'( ?
You don't need to provide that bloc argument explicitly. It will do an automatic lookup.
@override
Widget build(BuildContext context) {
return BlocProvider<MapBloc>(
create: (context) => MapBloc(),
child: BlocListener<MapBloc, MapState>(
// bloc: BlocProvider.of<MapBloc>(context), // remove this
listener: (context, MapState state) {
print("test");
},
child: Material(),
),
);
}
Either way, I believe it should work.
Cc @felangel
Thx for your reply, unfortunately problem still here :
Widget build(BuildContext context) {
return BlocProvider<MapBloc>(
create: (context) => MapBloc(),
child: BlocListener<MapBloc, MapState>(
listener: (context, MapState state) {
print("test");
},
child: Scaffold(
body: Center(
child: IconButton(
icon: Icon(Icons.map),
onPressed: () {
final MapBloc map = BlocProvider.of<MapBloc>(context);
},
),
),
),
),
);
}
Same error on onPressed callback :'(
BlocProvider.of() called with a context that does not contain a Bloc of type MapBloc.
@EArminjon can you extract that BlocListener and it's subtree to another widget and try if that passes?
Widget build(BuildContext context) {
return BlocProvider<MapBloc>(
create: (context) => MapBloc(),
child: ThatNewWidget(), // extract to new widget
);
}
@tenhobi It works.
So, it's a bug :'(
This trix will create a lot of boiler-plate : i will create an other widget each time I need to use BlocProvider...
I don't think it's a bug per se. It's more how Flutter works. To be able to access some provided thing, you have to look up from someplace in the subtree.
That is theoretically done here too, bud you use the same context variable, and I am not sure how that affects all of that. @felangel might know more about this tho.
@EArminjon this is not a bug because you can't access a bloc from the same context in which it was provided. If you don't want to create another widget then you can wrap the BlocProvider.of in a Builder to get a new context.
Builder(
builder: (context) {
BlocProvider.of<MyBloc>(context);
}
)
Thank you @felangel, I will use Builder :) !
So it was like I thought.
Btw. you are not able to access things from any widget, but here is the "issue" that you are using the context (which is used for lookups) not from those widgets, but as you are the widget where is this build function placed, right?
No problem! @tenhobi made a suggestion to extract the code that needs access to the bloc into a separate widget and I personally recommend that as well because it allows you to inject a mock bloc when you are doing widget tests and also keeps your code more modular and reusable. Hope that helps and closing for now but feel free to comment with additional questions or comments and I'm more than happy to continue the conversation 馃憤
Most helpful comment
@EArminjon this is not a bug because you can't access a bloc from the same context in which it was provided. If you don't want to create another widget then you can wrap the BlocProvider.of in a Builder to get a new context.