Quick Tip #5 — sync*, a taste of the future
How to build dynamic lists of widgets?
This is one of the most common issues faced by Flutter developers.
Indeed, the List literal is not easy to work with and creating a complex list can be a painful experience — be it conditionally adding a widget in a
Column or concatenating a
children argument with custom logic.
As such, it is not uncommon to find code that looks like this:
Do you have trouble reading this example? Don’t worry, me too.
This horror is due to a combination of facts:
- Dart does not have a spread operator
- Widgets do not allow
nullas a valid child
- Widgets are supposed to be entirely immutable. So building the list in multiple steps doesn’t feel right.
These facts led to “Allow null values in child or children collections” be one of the most upvotes issues on Flutter’s GitHub.
And we’ve been heard!
While Flutter will still not allow
null as a valid widget, it has been decided to fix these issues directly in Dart instead.
As such, two new languages features have been drafted and recently got flagged as “being implemented”:
With these two combined, our previous example becomes the following:
That’s much better!
But what can we do right now?
While new features are cool, there is no official release date. We can’t just pause our development until these are available. We need a temporary solution to this problem.
Fact is, these new syntaxes are nothing but a syntax sugar over
sync* functions. As such, we can already use them by writing a
sync* function ourselves!
sync* functions, our example now becomes:
This example is not perfect, for sure. But it is infinitely better than our first attempt using List literal.
We have access to the spread operator through
for too with their usual syntax combined to
This is more robust as we’re not filtering
null anymore, which could hide potential mistakes. And we’re not creating our list through mutation either, which is in accordance to the immutability principle of widgets.
This is also more flexible because we have the full power of a function; as opposed to the limited methods that
The future is very promising, with spread operator and conditional addition to List literal.
Fortunately, we already have access to these features through a slightly less convenient syntax, using
We can start by using the
sync* equivalent, and once these new features lands, easily convert to a cleaner syntax with no behavioral change.
The latest Tweets from Remi Rousselet (@remi_rousselet): "I've just published a port of React hooks to flutter…twitter.com