Kinda Code
Home/Flutter/Flutter FutureBuilder example (updated)

Flutter FutureBuilder example (updated)

Last updated: June 05, 2023

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).

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:

You can also check out our Flutter category page, or Dart category page for the latest tutorials and examples.