My initial state set in my Bloc constructor super call WILL trigger the BlocBuilder, but no state changes after that will work. Yes, my state class is extending Equatable. I have gone through every topic on SO regarding bloc emit state not working and have checked everything. The only difference in this app as opposed to other apps I have bloc working, is that I have a Cubit and Bloc in this app, that should not matter I don’t think. Other than that for the life of me cannot figure out what is the problem here.
I initiate a new Bloc event with get_it like this:
getIt().add(GetLocation( LocationRequestModel() );
main.dart:
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => PlacesCubit()),
BlocProvider(create: (conetxt) => LocationBloc(getIt())),
],
child: MaterialApp.router(
title: 'Great Places',
theme: AppTheme.darkTheme,
routerConfig: _appRouter.config(),
));
}
UI / Widget:
@override
Widget build(BuildContext context) {
return Column(children: [
Container(
decoration: boxWithBorder(context),
alignment: Alignment.center,
height: 170,
width: double.infinity,
child: _locationBloc(),
...
...
_locationBloc() {
return BlocBuilder<LocationBloc, LocationState>(
builder: (ctx, state) {
if (state is LocationNotInitiated) {
return _noLocationText(false);
} else if (state is LocationLoading) {
return const CircularProgressIndicator();
} else if (state is GetLocationError) {
return _noLocationText(true);
}
//TODO sucess here!
return const Column();
});
}
state class:
abstract class LocationState extends Equatable {
const LocationState();
@override
List<Object?> get props => [];
}
class LocationNotInitiated extends LocationState {
const LocationNotInitiated();
@override
List<Object?> get props => [];
}
class LocationLoading extends LocationState {
const LocationLoading({required this.test});
final String test;
@override
List<Object?> get props => [test];
}
bloc:
class LocationBloc extends Bloc<LocationEvent, LocationState> {
final GetLocationUseCase _getLocationUseCase;
LocationBloc(this._getLocationUseCase) : super(const LocationNotInitiated()) {
on<GetLocation>(
(event, emit) async {
//just testing here
await Future.delayed(const Duration(milliseconds: 250));
// LocationLoading state will not be emitted!
emit(const LocationLoading(test:"testing"));
},
);
}
}
2
Answers
I changed the way I initiated my event from using get_it to Bloc's :
and now I see states being propagated back to my LocationBloc.
So that fixes the issue in this app but raises the question: Why does get_it not work in this app to trigger bloc events but works in other apps I have worked on. I did try registerFactory and registerSingleton and neither worked for injecting Bloc (and receiving events). Maybe because I have a Cubit and Bloc in this app?....hmmmmm.
Blocs are created here:
This means that you don’t get them from getIt. So, when you were trying to fire event with:
it gave you some other bloc instance. when you do:
you’ve got correct instance, that were created in the tree above.
and of course it’s no matter that you have and bloc, and cubits in your app.