FlutterFirebase
FlutterFirebase

Reputation: 2353

How to catch error in ChangeNotifier after widget deactivated?

I have code in Model for execution. I provide Model with Provider. But if Model is dispose before finish execution I get error:

E/flutter (26180): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: A Model was used after being disposed. E/flutter (26180): Once you have called dispose() on a Model, it can no longer be used.

For example Model is dispose if user press back button so Navigator.pop(). This because Model is only scope to this Widget.

But that mean I cannot catch error in Model?

My code:

class Model extends ChangeNotifier {

  bool error = false;

  func() {

    try {

    await execute();
    error = false

    } catch {
    error = true;
    print(e.toString());
    }

  }

}



class ExampleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

return ChangeNotifierProvider(
      builder: (context) => Model(),
child: Consumer<Model>(builder: (context, model, _) {
return FloatingActionButton(
  child: model.error ? Icon(Icons.error) : Icon(Icons.check),
  onPressed: () {
    model.func();
  }
);

    …

How I can catch error in Model after dispose?

Upvotes: 2

Views: 2834

Answers (1)

wamfous
wamfous

Reputation: 2329

I just had the same problem.

The error occurs because you use one of the ChangeNotifier methods, usually notifyListeners() (which I'm assuming you're calling, but left out of the pasted code) after dispose() has been called. By the way, it's an assert error, so only in debug builds.

To get rid of the error, you could check if the object has been disposed before calling notifyListeners() with your own flag:

class Model extends ChangeNotifier {
  bool error = false;
  bool isDisposed = false;

  func() {
    try {
      await execute();
      error = false
    } catch {
      error = true;
      print(e.toString());
    }

    if (!isDisposed) {
      notifyListeners();
    }
  }

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

Upvotes: 9

Related Questions