How to use FutureBuilder in Flutter

How to use FutureBuilder in Flutter

With FutureBuilder in Flutter, you can construct your user interface depending on the outcome of a future. Common applications include displaying data from an API in an app’s user interface after retrieving it asynchronously.

What is FutureBuilder in Flutter

FutureBuilder in Flutter is a widget in Flutter that provides a way to asynchronously build widgets based on the state of a Future. A Future is an object in Flutter that represents a value that may not be available yet. FutureBuilder takes a Future and builds a widget tree based on its state, which can be one of three states:

  1. Future hasn't completed yet: While the Future is still in progress, FutureBuilder displays a loading indicator or any other widget that you specify as a placeholder until the Future completes.
  2. Future completed with data: When the Future completes with data, FutureBuilder passes the result to a builder function that you provide. The builder function takes the data and returns a widget tree to display it.
  3. Future completed with an error: When the Future completes with an error, FutureBuilder calls the errorBuilder function that you provide to build a widget tree to display the error message.

FutureBuilder in Flutter takes a Future and two builder functions as arguments:

  1. Future: The asynchronous task that will be utilized to populate the widget hierarchy with its result.
  2. builder: A callback function that is called when the Future completes with data. It takes the completed data and returns a widget tree to display it.
  3. errorBuilder: A callback function that is called when the Future completes with an error. It takes the error message and returns a widget tree to display it.

You may use FutureBuilder in your Flutter app to process and show the results of asynchronous operations like network requests, database queries, and file I/O in a widget tree.

The Future to wait for and the builder function to use to generate the tree of widgets based on that Future are the two mandatory inputs to the FutureBuilder in Flutter widget.

Example of how to use FutureBuilder in flutter:

FutureBuilder(
  future: fetchData(),
  builder: (BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    } else if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    } else {
      return Text('Data: ${snapshot.data}');
    }
  },
);

The FutureBuilder is in a waiting state until the fetchData() method is finished. While waiting, the CircularProgressIndicator widget is shown. If an error occurs, the Text widget shows the error message. If the future is successful, the Text widget displays the returned data.

How to use FutureBuilder in Flutter

Complete code:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({
    Key? key,
  }) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  Future<List> _getData() async {
    var response =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));

    if (response.statusCode == 200) {
      List data = json.decode(response.body);
      List titles = [];

      for (var item in data) {
        titles.add(item['title']);
      }

      return titles;
    } else {
      throw Exception('Failed to load data');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Row(children: [
          Image.asset(
            'assets/logo.png',
            height: 30,
          ),
          Text('flutterflux.com')
        ]),
      ),
      body: Center(
        child: FutureBuilder(
          future: _getData(),
          builder:
              (BuildContext context, AsyncSnapshot<List> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    title: Text(snapshot.data![index]),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

An HTTP GET request is sent from the app via the http package to the JSONPlaceholder API, which returns a collection of blog entries. The postings’ titles are extracted as a list of strings when the answer is interpreted as JSON. When the data is being retrieved, a CircularProgressIndicator widget is displayed by means of the FutureBuilder in flutter widget; after complete, a ListView widget displays the list of titles. If there is a problem while retrieving the data, the Text widget will show a suitable error message.

How to reload FutureBuilder in Flutter

The FutureBuilder widget is utilized to asynchronously collect data from a data source and construct user interface components accordingly.

In order to reload the FutureBuilder in Flutter widget, you must force the future to be rebuilt. Many options exist, each dependent on the data retrieval technique used.

  • Applying setState To re-create a widget after using setState to alter its state, just re-call the method in question. Example:
import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  final GlobalKey _refreshIndicatorKey = GlobalKey();
  Future _getData() async {
    var response =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    if (response.statusCode == 200) {
      List data = json.decode(response.body);
      List titles = [];
      for (var item in data) {
        titles.add(item['title']);
      }
      return titles;
    } else {
      throw Exception('Failed to load data');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Row(children: [
            Image.asset(
              'assets/logo.png',
              height: 30,
            ),
            Text('flutterflux.com')
          ]),
        ),
        body: RefreshIndicator(
          key: _refreshIndicatorKey,
          onRefresh: () async {
            _reload();
            setState(() {});
          },
          child: FutureBuilder(
            future: _getData(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(snapshot.data![index]),
                    );
                  },
                );
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ));
  }

  void _reload() {
    setState(() {});
  }
}

We create a GlobalKey called _refreshIndicatorKey for the RefreshIndicator widget in this example. When the user pulls down on the RefreshIndicator, the onRefresh method is triggered, which calls setState to rebuild the FutureBuilder. To initiate a reload programmatically, we define a _reload method that also calls setState.

There are several options for initiating a reload of a FutureBuilder in Flutter, and the one you choose will depend on the data source and the reload’s purpose.

Conclusion

The FutureBuilder widget is utilized to asynchronously collect data from a data source and construct user interface components accordingly. It’s frequently employed in scenarios when information must be retrieved from a network or database, and the user interface must be modified in light of the anticipated outcome. read too Firebase auth in Flutter

Hello, I'm Cakra. I'm currently occupied with developing an application using the Flutter framework. Additionally, I'm also working on writing some articles related to it.

You May Also Like