6

I'm getting this error message:

Unhandled Exception: A ModeManager was used after being disposed.

I'm using ChangeNotifier (class ModeManager) together with ChangeNotifierProvider. Build method, where I create Provider looks like this:

@override
Widget build(BuildContext context) {
    return !_isLoaded ? Center(child: CircularProgressIndicator()) : ChangeNotifierProvider(
        create: (_) => ModeManager(_appUser),
        child: Scaffold(
            appBar: AppBar(
            title: Text('Connect Spotify'),
            ),
            body: AddSpotifyScreenBody(),
        ),
    );
}

Widget where I use provider looks something like this:

class _AddSpotifyScreenBodyState extends State<AddSpotifyScreenBody> {
  @override
  Widget build(BuildContext context) {
    var provider = Provider.of<ModeManager>(context);
    return Center(
      child: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: <Widget>[
            Text(provider.isCollecting ? 'COLLECTING NOW' : 'SHARING NOW'),
            //...some other widgets using provider...
          ],
        ),
      ),
    );
  }
}

Does anybody know what could cause this error or what am I doing wrong? Thank You very much.

cavargov
  • 415
  • 5
  • 6

2 Answers2

37

It seems that you call notifyListeners() after disposing the widget with the ChangeNotifierProvider() . This happened with me when a Future function call notifyListeners(). As mentioned here, you can override the notifyListeners method in the ChangeNotifier class :

@override
void dispose() {
  _disposed = true;
  super.dispose();
}

@override
void notifyListeners() {
  if (!_disposed) {
    super.notifyListeners();
  }
}

don't forget to declare the variable bool _disposed = false;

Ismaeel Sherif
  • 555
  • 7
  • 15
  • 1
    Any idea how one could go about debugging this if `dispose()` is never called on the ChangeNotifier? At least the `print` statement in there never prints. – sleighty Sep 23 '21 at 07:43
  • @BrunoEly , Check if the ChangeNotifier is declared as a global provider or it's ChangeNotifierProvider is still in the widget tree – Ismaeel Sherif Dec 25 '21 at 14:50
0

Override dispose() in Widget cancel whatever work performFetch and expensiveOperation are doing, so that performFetch never actually calls notifyListeners.

You don't need to remove the listener before calling dispose, dispose clears the listener list.

Ricky
  • 103
  • 7