according to the flutter_bloc documentation it is sufficient to wrap a widget with Bloc Provider in order to use the Bloc instance from the widget. However, I am getting this error:
No ancestor could be found starting from the context that was passed to BlocProvider.of().
My code is very simple, structured in the following way:
login_screen.dart
class LoginPage extends StatefulWidget {
const LoginPage({super.key, required this.title});
final String title;
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwortController = TextEditingController();
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AuthenticationBloc(),
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Username
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _usernameController,
decoration: const InputDecoration(
labelText: "Email",
border: OutlineInputBorder()
),
),
),
//Passwort:
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _passwortController,
obscureText: true,
decoration: const InputDecoration(
labelText: "Password",
border: OutlineInputBorder()
),
),
),
//Login button
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 50)
),
onPressed: () {
BlocProvider.of<AuthenticationBloc>(context).add(
LoginEvent(_usernameController.text, _passwortController.text)
);
},
child: const Text('Log in')
),
const SizedBox(height: 20,),
//Register button
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 50)
),
onPressed: () async {
},
child: const Text('Register')
),
],
),)
),
);
}
}
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await service_registration.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const LoginPage(title: 'Flutter Demo Home Page'),
);
}
}
Any idea why this is happening?
2
Answers
Have you tried to rename "context" in create parameter to something else?
from:
to
Sometimes happens to get the wrong context and, obviously, there will be no Bloc there.
But I highly recommend you to provide blocs right before MaterialApp, on MyApp class. Just like below:
By doing this, you can access your bloc anywhere your application. Just be aware to not fetch a big amount of data right on blocstart
BlocProvider.of() Fails to Find Bloc
The problem is that BlocProvider.of() is using the context that was provided for BlocProvider.
There are many ways to solve this issue; you just need to ensure that blocProvider.of() uses the child BuildContext. For example, you can wrap your Scaffold with BlocBuilder(), BlocConsumer(), or Builder().