Flutter
Loading state
Show loading and error states with FutureBuilder.
State with FutureBuilder
FutureBuilder watches a Future and rebuilds the UI based on the snapshot it provides. You pass the Future to the future parameter and a function taking an AsyncSnapshot to the builder parameter. While waiting you show a loading indicator, and on error you show an error message.
FutureBuilder<Weather>(
future: weatherFuture,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Hata: ${snapshot.error}');
}
return const CircularProgressIndicator();
},
)
AsyncSnapshot and connection state
AsyncSnapshot carries the state of the Future. You check snapshot.connectionState against ConnectionState.waiting to catch loading, and snapshot.hasData to know whether data has arrived.
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Hata: ${snapshot.error}');
}
return Text(snapshot.data!.sehir);
}
Exercise State handling with FutureBuilder
Write a build method that returns a FutureBuilder<Weather>. While loading show CircularProgressIndicator, on error show Text('Hata'), and when data arrives show Text(snapshot.data!.sehir).
Show example solution
import 'package:flutter/material.dart';
class Weather {
final String sehir;
final double sicaklik;
Weather(this.sehir, this.sicaklik);
}
class WeatherScreen extends StatelessWidget {
final Future<Weather> future;
const WeatherScreen({super.key, required this.future});
@override
Widget build(BuildContext context) {
return FutureBuilder<Weather>(
future: future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return const Text('Hata');
}
return Text(snapshot.data!.sehir);
},
);
}
}
void main() {
print('hazir');
}
Test yourself
-
What is shown while FutureBuilder is loading?
- The data automatically
- An empty screen
- An error message
- A loading indicator (e.g. CircularProgressIndicator)
Show answer
A loading indicator (e.g. CircularProgressIndicator) — During waiting the connectionState is waiting; you show a loading indicator. Data has not arrived yet, an empty screen is a poor experience, and an error message is shown only when hasError is true.
-
Catch the loading state
builder: (context, snapshot) {
if (snapshot.connectionState == ____) {
return const CircularProgressIndicator();
}
return Text(snapshot.data!.sehir);
}
Show answer
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
return Text(snapshot.data!.sehir);
}
-
FutureBuilder parts
- future
- The Future being watched
- builder
- Function that builds the UI
- snapshot.connectionState
- Connection state
- snapshot.hasError
- Whether there is an error
Next lesson: Summary - Weather app