I'm new to Flutter, and also new to Bloc use.
I have an error when compiling the code:
The following assertion was thrown building Login(dirty, state: _LoginFormState#44e7f):
BlocProvider.of() called with a context that does not contain a Bloc of type BtnBloc.
No ancestor could be found starting from the context that was passed to
BlocProvider.of<BtnBloc>().
This can happen if the context you use comes from a widget above the BlocProvider.
This can also happen if you used BlocProviderTree and didn't explicity provide
the BlocProvider types: BlocProvider(bloc: BtnBloc()) instead of BlocProvider<BtnBloc>(bloc:
BtnBloc()).
The context used was: Login(dirty, state: _LoginFormState#44e7f)
I've tried to change some stuff in my bloc class, but nothing does about it.
Here is my blog class :
class BtnBloc extends Bloc<BtnEvent, BtnState> {
@override
BtnState get initialState => BtnState.initial();
@override
Stream<BtnState> mapEventToState(
BtnState currentState, BtnEvent event) async* {
if (event is IdleEvent) {
yield currentState..state = 1;
} else if (event is LoadingEvent) {
yield currentState..state = 1;
} else if (event is RevealEvent) {
yield currentState..state = 2;
}
}
}
And here is my build method :
final _btnBloc = new BtnBloc();
_LoginFormState(
{Key key,
this.primaryColor,
this.backgroundColor,
this.backgroundImage,
this.logo});
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: _btnBloc,
child: BlocBuilder<BtnEvent, BtnState>(
bloc: BlocProvider.of<BtnBloc>(context),
builder: (context, BtnState state) {
return myWidget();
Please help me :'(
After the while of time facing this problem, I hope this article will help you to understand more about context
.
The general solution is the same as the @Filled Stacks's answer. It means that you have to pass the bloc when navigating into a new page, so the BlocProvider
can find which type of Bloc you will be received.
I recommend initing the main function for the overall application which will init your screens and context through the screens. For eg:
class ListTodoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider<TodoBloc>(
create: (context) => TodoBloc(TodoDao())..add(QueryTodoEvent()),
child: ListTodoPageful());
}
}
class ListTodoPageful extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ListTodoState();
}
}
class ListTodoState extends State<ListTodoPageful> {
TodoBloc _todoBloc;
@override
Widget build(BuildContext context) {
_todoBloc = BlocProvider.of<TodoBloc>(
context);
//...
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => BlocProvider.value(
value: _todoBloc, child: CreateTaskPage())));
}
//...
}
class _CreatePageState extends State<CreateTaskPage> {
TodoBloc _todoBloc;
@override
Widget build(BuildContext context) {
_todoBloc = BlocProvider.of<TodoBloc>(context);
}
Refer to my sample application here: https://github.com/huynguyennovem/flutter_todo
The line below is your problem. The error is exactly what the message says.
...
child: BlocBuilder<BtnEvent, BtnState>(
bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
builder: (context, BtnState state) {
...
The context you're using there does not have a BlocBuilder attached to it so nothing is passing the BloC down from the top to your LoginState. You can either
If this is your first view then use 1.
Change
bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
To
bloc: _btnBloc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With