← Flutter / Dart

Flutter / Dart · 08 / 18

Null safety, errors and Future

Handle missing values and wait for an asynchronous result.

  • Small
  • Basics
  • 15 min

Prerequisites: Classes and constructors

Some tasks take time, such as reading a file. A Future promises a later result or error. async permits await inside a function. await waits for that task without automatically creating parallel CPU work. Missing values and failed tasks are two different cases.

Example files

01Return a result later

loadName returns Future<String?>. Its result may be text or null. Future.delayed simulates a delay. A real app might read a file or database instead.

async.dart · dartOpen file
Future<String?> loadName() async {
  await Future<void>.delayed(const Duration(milliseconds: 100));
  return null;
}

Future<void> main() async {
  try {
    final name = await loadName();
    print(name ?? 'No vehicle yet');
  } catch (error) {
    print('Loading failed: $error');
  }
}

Run / check

dart run async.dart

02Use await and ??

await loadName() yields the eventual value. ?? then handles only null. A thrown exception instead skips normal result processing and reaches catch.

03Handle errors visibly

Try changing loadName to throw StateError("Cannot load"). The error message shows the other path. An interface will later distinguish loading, success, empty data and failure. A missing name must not silently become a successful load containing invented data.

Expected result

After a short delay: No vehicle yet

Your exercise

Return Family car instead of null. Then remove await and observe the result type.

Show the solution and explanation

With await you receive String?. Without await you receive Future<String?>. That is the unfinished task rather than the completed name. Restore await before processing the name.

Project context and sources

The example is simplified for learning. The linked source version shows its use in the project and the checks applied there.