Loading state
- Flutter course
- Intermediate
- Lesson 64/99
- 4 min
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);
}Practice 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).
Starter code
import 'package:flutter/material.dart';
class Weather {
final String sehir;
final double sicaklik;
Weather(this.sehir, this.sicaklik);
}
// WeatherScreen sınıfını yaz
// build metodu FutureBuilder döndürsün
// yükleme durumunda yükleme göstergesi
// hata durumunda Text('Hata')
// veri geldiğinde sehir alanını göster
void main() {
print('hazir');
}Sample 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');
}Expected output
hazir
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is shown while FutureBuilder is loading?
- The data automatically
- An empty screen
- An error message
- A loading indicator (e.g. CircularProgressIndicator) Correct answer
Explanation: 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.
2 Catch the loading state
builder: (context, snapshot) {
if (snapshot.connectionState == ____) {
return const CircularProgressIndicator();
}
return Text(snapshot.data!.sehir);
}
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
return Text(snapshot.data!.sehir);
}
Explanation: To catch the waiting state you check ConnectionState.waiting. active, none, and done do not represent loading; done means completed.
3 FutureBuilder parts
| Term | Meaning |
|---|---|
future |
The Future being watched |
builder |
Function that builds the UI |
snapshot.connectionState |
Connection state |
snapshot.hasError |
Whether there is an error |