wei
wei

Reputation: 677

access BlocProvider.of<Bloc>(context) in dispose method

does anyone have any idea of how I can do this?

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()) instead, 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!

Upvotes: 12

Views: 6576

Answers (2)

Philipos D.
Philipos D.

Reputation: 2310

A small more detailed approach:

sound null safety, you can use @Omatt answer.

unsound null safety, you can use the following approach:

Declare a static variable inside the class and assign it inside init or build as follows:

class MyAwesomeWidget extends StatefulWidget {
  const MyAwesomeWidget({
    Key key,
  });

  @override
  _MyAwesomeWidgetState createState() => _MyAwesomeWidgetState();
}

class _MyAwesomeWidgetState extends State<MyAwesomeWidget> {
  FiltersBloc filtersBloc;

  @override
  void initState() {
    super.initState();
    new Future.delayed(Duration.zero, () {
      filterBloc = BlocProvider.of<FiltersBloc>(context);
    });
  }

  @override
  void dispose() {
    filterBloc.myFunction();
    super.dispose();
  }
}

Upvotes: 0

Omatt
Omatt

Reputation: 10463

BlockProvider needs context to be initialized. You may initialize it on the screen's Widget build()

late FiltersBloc filtersBloc;

@override
Widget build(BuildContext context){
  filtersBloc = BlocProvider.of<FiltersBloc>(context);
  return ...
}

...then call the desired method on dispose()

@override
void dispose() {
  filtersBloc.dispatch();
  super.dispose();
}

Upvotes: 13

Related Questions