A missing delivery address and a delivery address that has not loaded yet are different situations. When both become an empty string, the interface loses information. Good null handling begins by deciding what absence means in your domain.

Make absence explicit

Dart types are non-nullable unless you add ?. Use a nullable field for information that may legitimately be unavailable. Validate required information at the boundary where you read an API response, local record, or form submission. This lets the rest of the application work with a useful model.

String displayName(String? input) {
  final value = input?.trim();
  if (value == null || value.isEmpty) {
    return 'Unnamed contact';
  }
  return value;
}

The fallback works for a contact label because the user can still identify the record through other details. It would be a poor rule for a payment amount. A missing amount should stop the operation and produce a clear validation error, rather than silently becoming zero.

Use assertions as promises you can prove

The null assertion operator ! tells Dart to treat a value as non-null and can throw if that promise is wrong. late shifts some initialization checks to runtime. Neither should be the default response to an analyzer warning. Often the warning reveals that loading, error, and loaded states have been combined in one loosely defined object.

Check shape before constructing a model

Dart patterns can validate and extract fields together. A parser should reject an invalid required identifier while allowing explicitly optional fields. Keep a distinction between an unsupported response shape and an empty successful result; users need different recovery actions for each.

Build a small boundary checklist

  • Document which fields may be omitted and which may be null.
  • Test an empty string separately from null.
  • Avoid fake defaults for prices, permissions, and account identifiers.
  • Keep malformed responses out of otherwise valid cached data.
  • Prefer readable validation over a chain of casts and assertions.

Start by searching a feature for !. For each occurrence, write the condition that makes it safe. If that condition depends on a remote server behaving perfectly, move the check into the parser.

Official references: Dart sound null safety and Dart patterns.