Issue
I have a parent widget that has two Blocs:
...
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<RestaurantBloc>(
create: (BuildContext context) => RestaurantBloc(restaurantRepository: _restaurantRepository),
),
BlocProvider<CartBloc>(
create: (BuildContext context) => CartBloc(),
),
],
child: RestaurantScreenWidget(),
);
}
...
Section of the parent widget where child widgets get generated using the CartBloc
and other Bloc:
...
BlocBuilder<RestaurantBloc, RestaurantState>(
builder: (context, state) {
if (state is RestaurantEmpty) {
return Center(
child: Text('Empty'),
);
}
if (state is RestaurantLoaded) {
final items = state.restaurantCategories;
if (items.length >= 1) {
return BlocBuilder<CartBloc, CartState>(
builder: (context, cartState) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <CategoryList>[
for (var item in items)
CategoryList(categoryName: item.name, categoryItems: item.items)
],
);
},
);
}
return Center(
child: Text('Empty restaurant'),
);
}
return Center(
child: Text(
'Error'
),
);
}
),
...
And then it generates various child widgets. Those widgets need access to CartBloc
and its state:
...
Padding(
padding: EdgeInsets.only(top: 20),
child: SizedBox(
width: double.infinity,
child: BlocBuilder<CartBloc, CartState>(
builder: (context, cartState) {
return RaisedButton(
child: const Text('ADD TO BASKET'),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {
BlocProvider.of<CartBloc>(context).add(
AddItemToCart(
itemCount: (state as ItemLoaded).amount,
itemPrice: args.itemPrice,
newItemId: args.itemId,
newItemRestrictions: (state as ItemLoaded).restrictions,
newItemName: args.itemName
)
);
Navigator.pop(context);
},
);
}
),
),
),
...
But by doing it like this, It gives the error:
However, if I put a MultiBlocProvider
with the CartBloc
on the child widgets, the error goes away, but obviously the parent widget doesn't shares the state of the child widgets.
How can I handle the state that needs to be share between these two widgets? (The generate child widgets push to a screen that needs access to CartBloc
and its state).
Solution
This is quite a common mistake. When using the BlocBuilder
widget, you must give it the bloc instance to 'build.' You can do this by setting the optional "bloc" constructor property in the BlocBuilder
.
BlocBuilder<CameraBloc, CameraState>(
bloc: CameraBloc(),
builder: (context, state) {
if (state is InitialCameraState) {
return Container(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller)));
}
return Container();
},
);
Answered By - Warren Snipes
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.