Reputation: 445
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.
Upvotes: 9
Views: 12721
Reputation: 2186
Created an extension for ChangeNotifier
based on @ismaeel Sherif's answer. If you are using classes extends ChangeNotifier
in multiple places, its safe to use an extension like this.
import 'package:flutter/material.dart';
class DisposeSafeChangeNotifier extends ChangeNotifier {
bool _disposed = false;
@override
void dispose() {
_disposed = true;
super.dispose();
}
@override
void notifyListeners() {
if (!_disposed) {
super.notifyListeners();
}
}
}
extend your class with DisposeSafeChangeNotifier
instead of ChangeNotifier
.
Upvotes: 1
Reputation: 103
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.
Upvotes: 0
Reputation: 710
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;
Upvotes: 45