This article shows you how to use the FutureBuilder widget in Flutter with a complete example.
In simple words, the FutureBuilder widget displays one thing while your Flutter application is handling HTTP requests and reading local data… and displays another thing when it’s done (usually the loaded results).
Table of Contents
Example
We’ll make a tiny Flutter app that fetches and displays some posts from an open API. While loading data, the app displays a CircularProgressIndicator. When done, it shows the posts instead.
The API URL (thanks to the Typicode team for providing awesome APIs for testing purposes):
https://jsonplaceholder.typicode.com/posts
A single post provided by the API has a structure like this:
{
"userId": 1,
"id": 3,
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
},
The Steps
Note: By using FutureBuilder, there is no need to call setState() in this example.
1. In order to easily send HTTP requests, we use the http package from pub.dev. Add the plugin to your project by executing the following command:
flutter pub add http
2. Remove all the unwanted stuff in lib/main.dart and add the following:
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
// import this to be able to call json.decode()
import 'dart:convert';
// import this to easily send HTTP request
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// this function is called when the app launches
Future<List> _loadData() async {
List posts = [];
try {
// This is an open REST API endpoint for testing purposes
const apiUrl = 'https://jsonplaceholder.typicode.com/posts';
final http.Response response = await http.get(Uri.parse(apiUrl));
posts = json.decode(response.body);
} catch (err) {
if (kDebugMode) {
print(err);
}
}
return posts;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Kindacode.com'),
),
// implement FutureBuilder
body: FutureBuilder(
future: _loadData(),
builder: (BuildContext ctx, AsyncSnapshot<List> snapshot) =>
snapshot.hasData
? ListView.builder(
// render the list
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, index) => Card(
margin: const EdgeInsets.all(10),
// render list item
child: ListTile(
contentPadding: const EdgeInsets.all(10),
title: Text(snapshot.data![index]['title']),
subtitle: Text(snapshot.data![index]['body']),
),
),
)
: const Center(
// render the loading indicator
child: CircularProgressIndicator(),
)));
}
}
3. Check the result:
Note: The loading process can take less or more time based on your internet speed. If you have a good internet connection, the loading indicator may be hard to see.
Conclusion
We’ve examined a full example of using FutureBuilder in Flutter to load data asynchronously from the internet. If you’d like to learn more new and interesting things about Flutter and mobile development, take a look at the following articles:
- Flutter and Firestore Database: CRUD example (null safety)
- Flutter + Firebase Storage: Upload, Retrieve, and Delete files
- Using GetX (Get) for Navigation and Routing in Flutter
- How to create a Filter/Search ListView in Flutter
- Great Plugins to Easily Create Animations in Flutter
- Best Libraries for Making HTTP Requests in Flutter
You can also check out our Flutter category page, or Dart category page for the latest tutorials and examples.