I’m encountering the following error in my Flutter application:
Error: Could not find the correct Provider<SettingsBloc> above this BlocListener<SettingsBloc, SettingsState> Widget
.
I’m using the GetIt and Injectable packages for dependency injection. Below are the relevant parts of my code:
settings_bloc.dart
@lazySingleton
class SettingsBloc extends HydratedBloc<SettingsEvent, SettingsState> {
// Bloc implementation
}
settings_page.dart
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
@override
Widget build(BuildContext context) {
return BlocListener<SettingsBloc, SettingsState>(
listenWhen: (previous, current) => previous.locale != current.locale,
listener: (context, state) => context.setLocale(state.locale),
child: BlocBuilder<SettingsBloc, SettingsState>(
builder: (context, state) {
return Scaffold();
},
),
);
}
}
app_router.dart
GoRoute(
path: '/tools',
pageBuilder: (context, state) => CustomTransitionPage(
key: state.pageKey,
child: ToolsPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
),
),
routes: [
GoRoute(
path: 'settings',
pageBuilder: (context, state) => CustomTransitionPage(
key: state.pageKey,
child: BlocProvider.value(
value: getIt<SettingsBloc>(),
child: const SettingsPage(),
),
transitionsBuilder: (context, primaryAnimation, secondaryAnimation, child) =>
FadeThroughTransition(
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
child: child,
),
),
routes: [
GoRoute(
path: 'theme_selection',
pageBuilder: (context, state) => CustomTransitionPage(
key: state.pageKey,
child: const ThemeSelectionPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
),
),
),
],
),
],
),
injection.config.dart
extension GetItInjectableX on GetIt {
GetIt init({
String? environment,
EnvironmentFilter? environmentFilter,
}) {
final gh = GetItHelper(
this,
environment,
environmentFilter,
);
final injectableModule = _$InjectableModule();
gh.factory<FirebaseAuth>(() => injectableModule.firebaseAuth);
gh.factory<GoogleSignIn>(() => injectableModule.googleSignIn);
gh.singleton<Logger>(() => injectableModule.logger);
gh.singleton<NotificationService>(() => injectableModule.notificationService);
gh.lazySingleton<SettingsBloc>(() => SettingsBloc());
// Other dependencies...
return this;
}
}
class _$InjectableModule extends InjectableModule {}
Issue:
When navigating to the SettingsPage
, I receive the error stating that the Provider<SettingsBloc>
cannot be found above the BlocListener. I’ve ensured that SettingsBloc
is registered as a lazySingleton in GetIt and provided it using BlocProvider.value
in the router.
Question:
What could be causing the Provider<SettingsBloc>
not to be found above the BlocListener
, and how can I resolve this issue to ensure that SettingsBloc
is properly provided to the SettingsPage
?
I attempted to wrap the MaterialApp.router()
with a MultiBlocProvider
and include SettingsBloc
as one of the providers. Here is the code snippet:
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => getIt<AuthBloc>()),
BlocProvider(create: (_) => SettingsBloc()),
],
child: MaterialApp.router(
// ... other configurations
),
);
}
2
Answers
Anywhere you are using
BlocListener
orBlocBuilder
orBlocConsumer
, you can provide your bloc object like this (with GetIt):As you have tagged your SettingsBloc as lazySingleton, I assume that you want to use it via service locator, not with direct creation