Hello, I am using flutter_bloc and leveraging the MultiBlocProvider widget. Things were working fine, and then at some point, my MultiBlocProvider just refused to instantiate any new Blocs I created and added to it. This is all pretty strange to me but i have tried anything and spent lots of time on this so i figured it is time to see if it is an issue. Let me know if there is anything else I can provide.
_Expectation:_
All bloc providers inside MultiBlocProvider should get instantiated.
_Actual Outcome_
Only the blocs that had been created successfully before that point are instantiated. The log does not output any events or transitions showing those blocs were created.
From my sample below, I had ItemListsBloc and CartBloc before this problem, and those continue to get instantiated correctly. The problem here is the LoadFaves bloc, and any other new blocs I have tried to add.
Here is my MultiBlocProvider:
````
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => ItemListsBloc()..add(LoadItemLists()),
),
BlocProvider(
create: (context) =>
FaveBloc()..add(LoadFaves('3pujK2EPXFaIPue3F42kSMTLgDV2')),
),
BlocProvider(
create: (context) => CartBloc()..add(CartInitialize()),
),
],
child: BlocBuilder
builder: (context, state) {
if (state is ItemListsLoaded) {
return Column(children: [
Categories(items: state.items.values.toList()),
SizedBox(
height: 10.0,
),
Expanded(
child: ListView(
shrinkWrap: true,
children: _buildItemLists(state.itemLists, state.items),
),
)
]);
}
return Container();
},
),
);
}
````
And here are the 'problematic' blocs:
````
class FaveBloc extends Bloc
final FavesRepository _favesRepository = FavesRepository.instance;
StreamSubscription _favesSubscription;
@override
FaveState get initialState => FaveInitial();
@override
Stream
FaveEvent event,
) async* {
if (event is LoadFaves) {
yield* _mapLoadFavesToState(event);
} else if (event is UpdateFaves) {
yield* _mapUpdateFavesToState(event);
}
}
Stream
_favesSubscription?.cancel();
_favesSubscription = _favesRepository.faves(event.userId).listen(
(faves) => add(UpdateFaves(faves)),
);
}
Stream
yield FavesUpdated(event.faves);
}
}
````
and
````
class OrderBloc extends Bloc
final OrderRepository _orderRepository = OrderRepository.instance;
StreamSubscription _ordersSubscription;
StreamSubscription _currOrderSubsction;
@override
OrderState get initialState => OrdersUnitialized();
@override
Stream
OrderEvent event,
) async* {
if (event is OrderCreated) {
yield* _mapOrderCreatedToState(event);
} else if (event is OrdersUpdated) {
yield* _mapOrderUpdateToState(event);
} else if (event is OrderLoadRequest) {
yield* _mapLoadReqToState();
}
}
Stream
_ordersSubscription?.cancel();
_ordersSubscription = _orderRepository.orders().listen(
(orders) => add(OrdersUpdated(orders)),
);
}
Stream
var orderId = await _orderRepository.createNewOrder(event.order);
var state = this.state as OrdersLoadSuccess;
yield state.copyWith(currentOrderId: orderId);
}
````
Thank you very much for your assistance.
Hi @ochmist 馃憢
Thanks for opening an issue!
By default, blocs are created lazily by BlocProvider
which means create
will not be called until the bloc is looked up via BlocProvider.of<T>(context)
. You can set lazy
to false on BlocProvider
to force the blocs to be created immediately.
BlocProvider(
lazy: false,
create: (_) => MyBloc(),
child: MyChild(),
)
Hope that helps 馃憤
Thank you so much for the lightning-quick response @felangel. Worked like a charm.
Quick question:
Can we put this somewhere in the docs as a note under MultiBocProvider? I read the whole thing and still spent lots of time debugging this. Maybe someone else could find it helpful.
Yeah it's in the API docs
Automatically handles closing the bloc when used with create and lazily creates the provided bloc unless lazy is set to false.
but I'll definitely include it in the README since it's easy to miss 馃憤
Amazing. Thank you very much.
One other question, would it be crazy to turn of lazy creation for blocproviders that are accompanied by the cascade (..) operator?
Most helpful comment
Thank you so much for the lightning-quick response @felangel. Worked like a charm.
Quick question:
Can we put this somewhere in the docs as a note under MultiBocProvider? I read the whole thing and still spent lots of time debugging this. Maybe someone else could find it helpful.