Hi, I'm having trouble trying to use BlocProvider.of
My code:
@override
void dispose() {
final FiltersBloc filtersBloc =
BlocProvider.of<FiltersBloc>(context);
super.dispose();
}
error is:
flutter: BlocProvider.of() called with a context that does not contain a Bloc of type FiltersBloc.
flutter: No ancestor could be found starting from the context that was passed to
flutter: BlocProvider.of<FiltersBloc>().
flutter:
flutter: This can happen if:
flutter: 1. The context you used comes from a widget above the BlocProvider.
flutter: 2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.
flutter:
flutter: Good: BlocProvider<FiltersBloc>(builder: (context) => FiltersBloc())
flutter: Bad: BlocProvider(builder: (context) => FiltersBloc()).
flutter:
flutter: The context used was: FiltersDrawer(dirty, state: _FiltersDrawerState#86e8a)
Also, if I follow the error code and use final filtersBloc = BlocProvider<FiltersBloc>(builder: (context) => FiltersBloc())
I cannot call filtersBloc.dispatch() anymore.
I know for initState, we can just didChangeDependencies instead. But I cannot find an equivalent for dispose.
Any help would be greatly appreciated. Thanks!
Hi @theweiweiway 馃憢
Thanks for opening an issue!
Can you please provide a link to a sample app which illustrates the problem you鈥檙e having? Thanks!
Thanks for the quick reply as always Felix,
The problem is quite simple, so please let me try to explain this below. If it's not enough, I'll be happy to provide a link to a sample app
I have a scaffold and a drawer that slides in and out. I need to dispatch events when the drawer closes. The drawer can be closed by:
It's very easy to dispatch an event for case 1. However, for 2., I can only seem to be notified of when the drawer slides out via the dispose method. Please see code below:
class _MyHomePageState extends State<MyHomePage> {
var _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return BlocProvider(
builder: (context) => DrawerBloc(),
child: Scaffold(
key: _scaffoldKey,
endDrawer: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
bottomLeft: Radius.circular(16)),
child: Drawer(child: MyDrawer())),
appBar: AppBar(
title: Text(widget.title),
),
body: Center(child: Text('hi')),
));
}
}
class MyDrawer extends StatefulWidget {
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
@override
void dispose() {
final DrawerBloc drawerBloc = BlocProvider.of<DrawerBloc>(context);
// dispatch event to bloc
// this is required because the user can SLIDE THE DRAWER OUT
}
_close() {
// I can easily dispatch event to bloc when the user taps this close button
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
FlatButton(onPressed: _close, child: Text('close')),
],
);
}
}
Please let me know if you would like to see sample code.
Thanks!
edit: sorry. didn't add the blocprovider
No problem! Sorry for the delayed response but this seems like a Flutter limitation (https://github.com/flutter/flutter/pull/37961). Also, you can't access InheritedWidgets
within dispose
so you would probably need to lookup the bloc via BlocProvider
in initState
and add/dispatch an event
to the same bloc instance (without doing a BlocProvider
lookup) from dispose
.
Hope that helps 馃憤
Thank You! In case anyone else needs to do something like this, I did:
FiltersBloc _filtersBloc;
@override
void dispose() {
_filtersBloc.dispatch(EventHere());
super.dispose();
}
@override
void didChangeDependencies() {
final FiltersBloc filtersBloc = BlocProvider.of<FiltersBloc>(context);
setState(() {
_filtersBloc = filtersBloc;
});
super.didChangeDependencies();
}
No problem! Also you don鈥檛 need setState and you can get the bloc in initState instead of didChangeDependencies 馃憤
ah, i see. OK, thanks!
Most helpful comment
No problem! Sorry for the delayed response but this seems like a Flutter limitation (https://github.com/flutter/flutter/pull/37961). Also, you can't access
InheritedWidgets
withindispose
so you would probably need to lookup the bloc viaBlocProvider
ininitState
and add/dispatch anevent
to the same bloc instance (without doing aBlocProvider
lookup) fromdispose
.Hope that helps 馃憤