0

Currently I have LOTS of this in a class (a ChangeNotifier so pretty much one for each field):

String _name;
String get name => _name;
set name(String value) {
  if (_name == value) {
    return;
  }
  _name = value;
  notifyListeners();
}

In C# I had the same problem with INotifyPropertyChanged, but there we can pass variables by reference, so it's easier to make a function for encapsulating this kind of behavior, and many libraries actually supply them.

I came up with this, but I am not sure if there are better (simpler) alternatives:

typedef ValueSetter<T> = void Function(T); // or imported from [ChangeNotifier]

...

String _name;
String get name => _name;
set name(String value) => _setAndNotifyIfNotEqual(_name, value, (v) => _name = v);

/// If [newValue] is different than [oldValue], call [setter] with [newValue],
/// then call [notifyListeners].
void _setAndNotifyIfNotEqual<T>(T oldValue, T newValue, ValueSetter setter) {
  if (newValue != oldValue) {
    setter(newValue);
    notifyListeners();
  }
}

Are there any better ways of achieving this in Dart?

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173
  • What would passing by reference accomplish here? – Jacob Phillips Aug 08 '19 at 22:07
  • Avoid the last `ValueSetter`, making the call a lot simpler, more readable and not depending on the caller to provide a correct setter function. – Michel Feinstein Aug 08 '19 at 22:09
  • Have you seen [ValueNotifier](https://github.com/flutter/flutter/blob/20e59316b8/packages/flutter/lib/src/foundation/change_notifier.dart#L257)? It seems like it might be more appropriate than just a ChangeNotifier here. – Jacob Phillips Aug 08 '19 at 22:20
  • I linked the wrong class before, fixed now. – Jacob Phillips Aug 08 '19 at 22:24
  • I don't think it will work for my use case. I am using a `ChangeNotifierProvider` in my Flutter `Widget`, so I can control state management in one class, like a ViewModel of sorts. This way I rebuild my UI parts that depend on the ViewModel state, once any of its properties change. – Michel Feinstein Aug 08 '19 at 22:45
  • If I use a `ValueNotifier`, I would have to create a `ValueNotifierProvider` so my `Widgets` can get it, but I have 5 `String` properties, and I could only provide one `String` `ValueNotifierProvider` to the tree. – Michel Feinstein Aug 08 '19 at 22:47
  • I guess I could create all the `ValueNotifier` I need inside my `ChangeNotifier` mode, than listen to the `ValueNotifier` notifications and raise a `ChangeNotifier` notification in case any of them fire a notification, but this adds as much boilerplate as before. – Michel Feinstein Aug 08 '19 at 22:50
  • ValueNotifier extends ChangeNotifier. You can use ChangeNotifierProvider with it. – Jacob Phillips Aug 08 '19 at 23:25
  • Yes, but it won't provide my ViewModel, it will provide one of its properties, so if I have 5 properties that are `String` how can I get one and not the other? As `Consumer` will fetch by type `String`. – Michel Feinstein Aug 08 '19 at 23:50

0 Answers0