Home > front end >  Provider not updating when property inside nested object changes
Provider not updating when property inside nested object changes

Time:03-18

I have a model which initializes multiple objects. Whenever a property inside one of the objects changes, the ui does not rebuild. I took care of overwriting the hash and == of the objects using Equatable so provider should detect the changes. Here is a sample from the code that shows the important parts:

class Tag extends ChangeNotifier with EquatableMixin {
  Tag(this._title, this._value, this._selected);

  final String _title;
  String _value;
  bool _selected;

  @override
  List<Object> get props => [_title, _value, _selected];

  String get title => _title;

  String get value => _value;
  set value(String newValue) {
    _value = newValue;
    notifyListeners();
  }

  bool get selected => _selected;
  set selected(bool newValue) {
    _selected = newValue;
    notifyListeners();
  }
}

class TagModel extends ChangeNotifier {
  TagModel() {
    _tag1.addListener(notifyListeners);
    _tag2.addListener(notifyListeners);
    _tag3.addListener(notifyListeners);
  }

  final Tag _tag1 = Tag("", "", false);
  final Tag _tag2 = Tag("", "", false);
  final Tag _tag3 = Tag("", "", false);

  Tag get tag1 => _tag1;
  Tag get tag2 => _tag2;
  Tag get tag3 => _tag3;
  

  //this function does not trigger a widget rebuild
  void loadTags() {
    _tag1.title = "tag 1";
    _tag2.title = "tag 2";
    _tag3.title = "tag 3";
  }
}

class TagPane extends StatelessWidget {
  const TagPane({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => context.read<TagModel>().loadTags(),
      )
    );
  }
}

CodePudding user response:

Try using Statefull Widget instead of Stateless than setState when pressing Elevated button. e.g

class TagPane extends StatefullWidget {
  const TagPane({Key? key}) : super(key: key);
  
  @override
  _TagPaneState createState() => _TagPaneState();
}

class _TagPaneState extends State<TagPane>{
  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => setState(() { 
          context.read<TagModel>().loadTags());
        ),
      )
    );
  }
}

CodePudding user response:

did you try adding a call to NotifyListeners() at the end of the method?

  • Related