I have a Message object, with optional string title and required string message

I want to display the title, or if it's null or empty, display the message.

Since the title could be an empty string "", I can't just write msg.title ?? msg.message.

Now I'm writing it like this:

// the Message object
String? title;
String message;

// display
Text(msg.title?.isEmpty ?? true
  ? msg.message
  : msg.title!)

This is ridiculously long and complicated. Is there a better way to do this?


Thanks everyone, I've learned a lot from your answers!<3


Solution 1: eamirho3ein

add this extension to string:

extension on String? {
  bool isNullEmpty => this == null && this.isEmpty;
}

and use it like this:

Text(msg.title.isNullEmpty ? msg.message: msg.title!)


Solution 2: Randal Schwartz

I came up with this the other day, and will be doing a screencast for my YT channel soon (https://www.youtube.com/c/RandalLSchwartzonDartandFlutter). Here's the code:

void main(List<String> arguments) {
  print('${Mine()}');
  print('${Mine(name: 'Bob only')}');
  print('${Mine(description: 'Guy only')}');
  print('${Mine(name: 'Bob and', description: 'Guy')}');

  print('${Mine(name: 'Bob', description: '')}');
  print('${Mine(name: '', description: 'Guy')}');
  print('${Mine(name: 'Bob', description: 'Guy')}');
}

extension IfEmptyOrNull on String? {
  operator [](String value) {
    if (this == null || this!.isEmpty) {
      return value;
    }
    return this!;
  }
}

class Mine {
  final String name;
  final String description;
  Mine({String? name, String? description})
      : name = name['No name'],
        description = description['No description'];

  @override
  String toString() => 'Mine(name: $name, description: $description)';
}

The fun part is that someValue[theDefault] is just an array syntax, and even makes sense.


Solution 3: Noah Tatko

Seems like your Message class could be cooler. Here's a dartpad with my stuff.

class Message {
  String? title;
  String message; // could be better named - message property in a message class? Consider `details`

  Message({required this.message, this.title});

  /// Safe method to get displayed text for this [Message].
  /// If the [title] is not null and is not empty, returns the title.
  /// If the [title] is null or empty, returns the [message].
  String get displayText {
    return title == null || title!.isEmpty ? message : title!;
  }
}

This would let you use message.displayText when you want to access the message.

// Some message
Message msg = Message(message: "Posted something successfully to the server", title: "Success!");

// The text widget
Text(msg.displayText);