Flutter could not find the correct Provider<Bloc> after navigating to different route
I found the reason for why my BlocBuilder couldn't find the CreateDidBloc
after navigating. That error occurs because navigating in Flutter pushes your page right below the MaterialApp in the widget tree. That means that my newly navigated Page is above the BlocProvider which is specified in the widget tree below the MaterialApp.
To fix this I just wrapped my MaterialApp with a MultiBlocProvider and the RepositoryProvider so that the Bloc is provided globally no matter in what route I am.
This is the important extract in which I can define the blocs globally:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RepositoryProvider(
create: (context) => CreateDidRepository(),
child: MultiBlocProvider(
providers: [
BlocProvider<LanguageBloc>(
create: (context) =>
LanguageBloc(LanguagePreference.getLanguage())),
BlocProvider<CreateDidBloc>(
create: (context) =>
CreateDidBloc(repo: context.read<CreateDidRepository>()))
],
child: BlocBuilder<LanguageBloc, LanguageState>(
builder: (context, state) {
return MaterialApp(...)
JonasLevin
Updated on December 29, 2022Comments
-
JonasLevin over 1 year
I'm using bloc to handle the state of a signup form. But I get the error:
Error: Could not find the correct Provider<CreateDidBloc> above this BlocBuilder<CreateDidBloc, CreateDidState> Widget
.
As you can see in the error I do use the blocCreateDidBloc
and the stateCreateDidState
and get them through a BlocBuilder.
The BlocBuilder is positioned in my "signup" page, which in my case is calledCreation
. The error occurs when I'm navigating from my introduction page to the creation page.
Below is an extract of myMaterialApp
in which I wrap the creation page with aRepositoryProvider
andBlocProvider
so that the creation page has access to the Bloc and repository. But for some reason does thecreation
page not find the BlocProvider for theCreateDidBloc
after navigating to the creation page.initialRoute: "/introduction", routes: { "/introduction": (context) => Introduction(), "/create": (context) => RepositoryProvider( create: (context) => CreateDidRepository(), child: BlocProvider( create: (BuildContext context) => CreateDidBloc( repo: context.read<CreateDidRepository>(), ), child: Creation(), ), ), },
This is how I navigate to the
Creation
screen:Navigator.push(context, PageTransition(type: PageTransitionType.fade, child: Creation()));
Creation (signup) page:
@override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: Column( children: [ Expanded( child: PageView( physics: const NeverScrollableScrollPhysics(), controller: _pageController, onPageChanged: (index) { setState(() => currentStep = index); }, children: [ Step1(), Step2(), Step3(), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ BlocBuilder<CreateDidBloc, CreateDidState>( builder: (context, state) { return ElevatedButton( onPressed: () { next(); }, child: Text(L.of(context).next)); }, ), BlocBuilder<CreateDidBloc, CreateDidState>( builder: (context, state) { return OutlinedButton( onPressed: state.formStatus is FormSubmitting ? null : cancel, child: Text(L.of(context).back)); }, ) ], ), const SizedBox( height: 16, ) ], ))); }
This is the stack trace:
When the exception was thrown, this was the stack #0 Provider._inheritedElementOf #1 Provider.of #2 ReadContext.read #3 _BlocBuilderBaseState.initState #4 StatefulElement._firstBuild
-
Dean Villamia over 2 yearsI feel like this is supposed to be in a documentation somewhere.. Anyways thanks for the HUGE help!!!