I'm using Flutter Bloc
for a project.
This is the structure:
MultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (context) {
return BlocA()
..add(FetchEvent());
},
),
BlocProvider<BlocC>(
create: (context) {
return BlocC()..add(FetchEvent());
},
),
],
child: IndexedStack(
index: _pageNum,
children: [
ChildA(),
ChildB(),
],
),
)
Inside ChildB
I have a Navigator.push()
to a ChildC
, where BlocC
is being used (BlocConsumer
), but I'm getting an error,
Flutter could not find the correct Provider above BlocConsumer<BlocC> Widget
Edit
There is a button in ChildB
that navigates to ChildC
on pressed.
Like,
TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
Navigator.push(context, CupertinoPageRoute(builder: (context) => ChildC()));
}
),
This is the bloc consumer in ChildC
// Child C
Scaffold(
body: BlocConsumer<BlocC, CState>(
builder: (context, state) {
if(state is CSuccessState) {
return _body();
} else if (state is CLoadingState || state is CInitState) {
return Center(child: CircularProgressIndicator());
} else return Center(child: Text("Something went wrong"));
},
listener: (context, state) {},
),
);
Edit 2
I found this answer, apparently, this is an issue when using Navigator.push
. Still, if anyone knows how to solve it in my case, do let me know
Provider is scoped.
It means only the subtree of your provider (your child widgets) can access it.
When you push a new page, it pushed it to the MaterialApp
router (default root router of your app), and your widget tree looks like:
MaterialApp
|- Provider
| |- TextButton (with onPressed: () => Navigator.push())
|- ChildC
As you can see, your ChildC
is not below the Provider
(s).
A way to solve it is to move your providers above your MaterialApp
:
Provider
|- MaterialApp
| |- TextButton (with onPressed: () => Navigator.push())
| |- ChildC
You can push your page to a nested router that is below your Provider
:
MaterialApp
|- Provider
| |- Router
| | |- TextButton (with onPressed: () => Navigator.push())
| | |- ChildC
BlockC
above ChildC
:TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
final blockCValue = context.read<BlockC>();
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => Provider<BlockC>.value(
value: blockCValue,
child: ChildC(),
),
);
},
),