5

Before Flutter introduced the null-safety feature, I was able to conditionally add Widgets within a list like so:

actions: <Widget>[
  canCancel
    ? CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () {
             Navigator.pop(context);
           },
      )
    : null,
].where(notNull).toList()

notNull being a homemade filter that filters off the null objects...

Now with null-safety it's impossible because the list of Widgets strictly has to be non-null. What would be a better approach?

1
  • add ? on canCancel so allows to have null Commented Apr 12, 2021 at 18:44

4 Answers 4

17

Just use if inside the List:

<Widget>[ 
   if (true) Widget(), 
]

Example with your code:

actions: <Widget>[
  if (canCancel)
    CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () {
             Navigator.pop(context);
           },
      ),
]
Sign up to request clarification or add additional context in comments.

2 Comments

Wow is that something "new" you can do in Flutter? Didn't know about this!
@Scaraux Not really. It was something like Dart 2.5 or 2.6 or something. It's called a "collection if".
5

Just replace your null with an empty, size zero, SizedBox.

SizedBox(width: 0, height: 0)

Or as suggested in comments:

SizedBox.shrink()

1 Comment

SizedBox.shrink() is the proper named constructor to achieve this.
2

As YoBo suggested, using collection-if is the better approach here, but if for some reason you need to be able to store nulls in a List and filter them out later (or if you just prefer your existing style), you can:

  1. Change your List type to allow nullable elements. That is, use <Widget?>[] instead of <Widget>[].
  2. Use Iterable.whereType with a non-nullable type to filter out null values.
actions: <Widget?>[
  canCancel
    ? CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () {
             Navigator.pop(context);
           },
      )
    : null,
].whereType<Widget>().toList();

1 Comment

This is a valid answer as well. I don't need to have null in the list though, the end goal was to conditionally insert the widget in a declarative manner. Thanks!
1

if is not new as it was added in Dart 2.3 a few years ago. Even before null-safety, you were not allowed to return a null for a widget. You might not see a compile-time warning before NNBD, but it is a runtime error.

As I mentioned in this answer (although that answer isn't for your case), you can use if condition or even ternary operator like this:

Column(
  children: [
    if (condition) Text(''),
    condition ? Text('') : Container(),
  ],
)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.