Introduction
Flutter provides various widgets to handle asynchronous operations, and FutureBuilder is one of the most powerful ones. It allows you to build UI dynamically based on the state of a Future. This tutorial will guide you through the fundamentals, best practices, and real-world examples of using FutureBuilder in Flutter.
What is FutureBuilder?
FutureBuilder is a Flutter widget that rebuilds itself based on the latest snapshot of an asynchronous operation. It is commonly used for API calls, database queries, or other asynchronous computations.
FutureBuilder Syntax
FutureBuilder<T>(
future: someFutureFunction(),
builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
// Handle different states here
},
)Parameters
future: TheFuturethat will be executed.builder: A function that returns a widget based on theAsyncSnapshotof theFuture.
Handling Different States in FutureBuilder
The AsyncSnapshot provides different states to handle:
ConnectionState.waiting→ Display a loading indicator.snapshot.hasError→ Handle errors properly.snapshot.hasData→ Display fetched data.- Else case → Handle empty or null data.
Example: FutureBuilder with Simulated Delay
import 'package:flutter/material.dart';
import 'dart:async';
class FutureBuilderExample extends StatelessWidget {
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 3)); // Simulate network delay
return "Hello, FutureBuilder!";
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("FutureBuilder Example")),
body: Center(
child: FutureBuilder<String>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text("Error: ${snapshot.error}");
} else if (snapshot.hasData) {
return Text(snapshot.data!, style: TextStyle(fontSize: 20));
} else {
return Text("No Data Available");
}
},
),
),
);
}
}Best Practices for Using FutureBuilder
✅ Do's
✔ Pass a Future to FutureBuilder, don't call the function inside builder.
✔ Handle all states properly – always check for loading, error, and data states.
✔ Use caching or state management to avoid redundant API calls.
✔ Use async/await for cleaner code instead of deeply nesting Future chains.
❌ Don'ts
❌ Avoid calling the future inside builder, as it will cause unnecessary rebuilds.
FutureBuilder(
future: fetchData(), // ✅ Correct
builder: ...
)Instead of:
FutureBuilder(
future: fetchData(), // ❌ Wrong - called inside builder
builder: (context, snapshot) {
fetchData();
return ...;
},
)Fetching Data from an API using FutureBuilder
Now, let's look at a real-world example where we fetch data from an API and display it in a ListView.
Example: Fetching User Names from an API
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
class FetchDataExample extends StatelessWidget {
Future<List<String>> fetchNames() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
List data = jsonDecode(response.body);
return data.map((user) => user['name'].toString()).toList();
} else {
throw Exception('Failed to load data');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Fetch API Data")),
body: FutureBuilder<List<String>>(
future: fetchNames(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ListTile(title: Text(snapshot.data![index]));
},
);
} else {
return Center(child: Text("No Data Available"));
}
},
),
);
}
}Conclusion
FutureBuilder is an essential widget for handling asynchronous operations in Flutter. By properly managing different states and optimizing API calls, you can create efficient and responsive applications.
This version enhances clarity, adds better structuring, and improves readability. Let me know if you need any further modifications! 🚀