HomebaseWorks
Lesson 2 of 4

Navigation, async data and Dart null safety

Move between screens and return results, load data with FutureBuilder correctly, and handle nullable values safely.

EWritten by the HomebaseWorks editorial team · reviewed 26 Oct 2026

Real apps move between screens, fetch data and deal with values that may be missing. These three areas carry many screening questions, and each has one common mistake to avoid.

Advertisement

Navigation and returning data

Navigator.push places a new route on top of the stack and returns a Future. Navigator.pop removes it and can send a value back:

final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (_) => const EditPage()),
);
if (result == 'saved') {
  _reload();
}

On the edit page, Navigator.pop(context, 'saved') completes that Future. If the user presses back instead, result is null, so always handle that case. Pass data into a screen through its constructor.

FutureBuilder without repeated requests

The common mistake is calling the fetch function inside build. Every rebuild then starts a new request. Create the Future once and store it:

late final Future<User> _userFuture;

@override
void initState() {
  super.initState();
  _userFuture = api.fetchUser(widget.id);
}

In the builder, handle three states: ConnectionState.waiting shows a spinner, snapshot.hasError shows an error and a retry option, and otherwise show the data. After an await inside a State, check mounted before calling setState or using context, because the user may have left the screen.

Dart null safety

  • String? may be null; String never is.
  • name?.length gives null instead of crashing when name is null.
  • name ?? 'Guest' supplies a default.
  • name! asserts it is not null and throws at runtime if you are wrong. Use it rarely.
  • late promises a value will be set before use, as with _userFuture above.

Packages

Dependencies go under dependencies in pubspec.yaml, and flutter pub get downloads them. Commit pubspec.lock in app projects so everyone builds with the same versions.

Checklist: every Future created outside build, every async screen has loading and error states, and every ! in your code has a clear reason.

Advertisement
Continue with Flutter4 lessons · 1 interview set · 1 test · 1 certificate
Not tested

More in Web and app