ChangeNotifier mounted equivalent?

Viewed 2004

I am extract some logic from Stateful Widget to Provider with ChangeNotifier: class Model extends ChangeNotifier {...}

In my Stateful Widget I have:

  if (mounted) {
setState(() {});
}

How I can check if Widget is mounted in Model?

For example how I can call:

 if (mounted) {
notifyListeners();
}
3 Answers

A simple way is pass 'State' of your Stateful Widget as a parameter to your 'Model'.

Like this:

class Model extends ChangeNotifier {

  Model(this.yourState);

  YourState yourState;

  bool get _isMounted => yourState.mounted;
}

class YourState extends State<YourStatefulWidget> {
  Model model;

  @override
  void initState() {
    super.initState();
    model = Model(this);
  }

  @override
  Widget build(BuildContext context) {
    // your code..
  }
}

I think you don't need to check the State is mounted or not. You just need to check the Model has been already disposed. You can override dispose() method in ChangeNotifier:

class Model extends ChangeNotifier {
  bool _isDisposed = false;

  void run() async {
    await Future.delayed(Duration(seconds: 10));
    if (!_isDisposed) {
      notifyListeners();
    }  
  }

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

And don't forget dispose Model when the State is disposed:

class YourState extends State {
  Model model;

  @override
  void initState() {
    super.initState();
    model = Model();
  }

  @override
  void dispose() {
    model?.dispose();
    super.dispose();
  }
  /// Your build code...

}

Or you can use ChangeNotifierProvider in package Provider, it will help you to dispose Model automatically.

class YourState extends State {
  Model model;

  @override
  void initState() {
    super.initState();
    model = Model();
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Model>(
      builder: (build) => model,
      child: Container(
        child: Consumer<Model>(
          builder: (context, model, widget) => Text("$model"),
        ),
      ),
    );
  }

}

as long as you wrap your widget with the provider model state and as it is known once your widget is disposed the provider model that is wrapping it already get disposed by default

so all you have to do is to define a variable isDisposed and modify the notifyListeners as below

MyState with ChangeNotifier{

// to indicate whether the state provider is disposed or not
 bool _isDisposed = false;


   // use the notifyListeners as below
   customNotifyListeners(){
    if(!_isDisposed){
       notifyListeners()
    }
   }




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

}

Just use a custom ChangeNotifier class.

import 'package:flutter/cupertino.dart';

class CustomChangeNotifier extends ChangeNotifier {
  bool isDisposed = false;

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

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