Replace getter and setter blocks with a oneliner when using ChangeNotifier.

When dart became ‘non-nullable by default’, an interesting keyword was added to the dart language: ‘late’.

Although it might not be so obvious at first glance, this keyword makes it possible to simplify getter and setter blocks when using a ChangeNotifier to update values on the screen.

Normally a getter and setter block does look like this.

int _counter = 0;

int get counter => _counter;

set counter(int value) {
  if (_counter != value) {
    _counter = value;
    notifyListeners();
  }
}

This code is not complicated. It consists of:

  • a private backing variable
  • a public getter and setter
  • some logic that tests if the value has changed and call ‘notifyListeners’ when needed

There are also some drawbacks:

  • You can access the backing variable directly (by accident).
  • It is easy to make mistakes like checking or assigning the wrong backing variable, especially when you have more than 3 pairs of getters and setters.
  • The code is boring (error-prone) and takes up too much space.
  • Don’t repeat yourself (DRY) principle is not respected.

Now with the ‘late’ keyword, we can replace the code above with this one-liner:

late final counter = Property<int>(0, notifyListeners);

Without the ‘late’ keyword this would not have been possible, because it is not allowed to access member functions (in this case notifyListeners) in an initializer. With the late keyword, initialization is deferred until it is first referenced.

The implementation of the Property class is simple and solves all drawbacks of a regular getter and setter block.

class Property<T> {
  Property(T initialValue, this.notifyListeners) {
    _value = initialValue;
  }

  late T _value;
  final void Function() notifyListeners;

  T get value => _value;

  set value(T value) {
    if (_value != value) {
      _value = value;
      notifyListeners();
    }
  }
}

This makes it possible to reduce the business-logic of the default Flutter counter app to these few lines:

class MainController extends ChangeNotifier {
  late final counter = Property<int>(0, notifyListeners);

  void incrementCounter() => counter.value++;
}

Source code to test this out can be found here:
https://github.com/jsroest/property_for_changenotifier

Published by Sander Roest

Professional app developer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: