As you try to inject Bloc or Cubit to your app, sometimes it maybe that you have the below error
- Providers are “scoped”. So if you insert of provider inside a route, then
- other routes will not be able to access that provider.
- Provider not found
- Could not find the correct Provider< > above this Widget
In general you get the error due to incorrect place bloc or provider injection.
Your MultiProvider or MultiBlocProvider should be at the very top and MaterialApp should be the child of MultiProvider or MultiBlocProvider
That’s as simple as that.
See if you can spot the error
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MultiBlocProvider(
providers: [
BlocProvider<AppCubits>(
create: (BuildContext context) => AppCubits(
data: DataServices(),
),
),
BlocProvider<SignInCubits>(
create: (BuildContext context) => SignInCubits(),
)
],
child: const AppCubitLogics(),
),
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
routes: {
"/signIn": (context) => SignIn(),
"/register": (context) => Register(),
},
theme: ThemeData(
appBarTheme: const AppBarTheme(
iconTheme: IconThemeData(
color: AppColors.primaryText,
),
elevation: 0,
backgroundColor: Colors.white)),
);
}
You may notice that we have MaterialApp right after return statement. Having a MaterialApp as your root is fine if you don’t use state management library like Getx, Riverpod, BLoC or Cubit.
So solve this issue we need to move MaterialApp down as a child of MultiProvider and MultiBlocProvider.
This way, you BlocProviders or Providers are available in the tree for all the children. Let’s see the correct way of doing it
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AppCubits>(
create: (BuildContext context) => AppCubits(
data: DataServices(),
),
),
BlocProvider<SignInCubits>(
create: (BuildContext context) => SignInCubits(),
),
BlocProvider<StorePageCubit>(
create: (BuildContext context) => StorePageCubit(),
)
],
child: MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
routes: {
//"/":(context) => WelcomePage(),
"/signIn": (context) => SignIn(),
"/register": (context) => Register(),
},
home: AppCubitLogics(),
theme: ThemeData(
appBarTheme: const AppBarTheme(
iconTheme: IconThemeData(
color: AppColors.primaryText,
),
elevation: 0,
backgroundColor: Colors.white)),
),
);
}
}
This way it’s guaranteed that, all the BlocProviders or Providers in providers List are given down to the children. It means both context and bloc would available wherever you want to access from.
Do remember that MultiBlocProvider extends MultiProvider