FutureBuilder Widget - Flutter Widget Guide By Flutter Agency

FutureBuilder Widget – Flutter Widget Guide By Flutter Agency

Hope you guys are doing amazing with Flutter. Earlier we have been through StreamBuilder Widget. In this article, we will understand What is FutureBuilder Widget along with how to use it in a Flutter.

What are Future Operations?

Asynchronous Functions

Asynchronous operations let your program continue other operations while the current operation is being performed. Dart uses Future objects to represent the results of asynchronous operations. To handle these operations, we can use Async/await, but it is not possible to integrate async and await on widgets. To solve this problem flutter introduced a widget called Future Builder.

What is FutureBuilder Widget in Flutter?

FutureBuilder Widget calls the future function to wait for the result, and as soon as it produces the result it calls the builder function where we build the widget.

The Default constructor of FutureBuilder Widget will look like below:

const FutureBuilder(
{Key? key,
required Future? future,
T? initialData,
required AsyncWidgetBuilder builder}
)

In the above constructor, all fields marked with @required must not be empty. Now let’s understand each property in detail.

Properties:

  • Key key: This attribute key controls how one widget replaces another widget in the tree.
  • initialData: This attribute is the data that will be used to create the initial snapshot. Providing this value presumably obtained synchronously somehow when the Stream was created ensures that the first frame will show useful data. Otherwise, the first frame will be built with the value null, regardless of whether a value is available on the stream: since streams are asynchronous, no events from the stream can be obtained before the initial build.
  • Future<T> future: This attribute will be the asynchronous computation to which this builder is currently connected, possibly null. If no future has yet completed, including in the case where the future is null, the data provided to the builder will be set to initialData.
  • AsyncWidgetBuilder<T> builder: The build strategy currently used by this builder.

The builder is provided with an AsyncSnapshot object whose AsyncSnapshot.connectionState property will be one of the following three values:

  • ConnectionState.none:  In this state future is null. The AsyncSnapshot.data will be set to initialData, unless a future has previously completed, in which case the previous result persists.
  • ConnectionState.waiting: In this state, future is not null but has not yet completed. The AsyncSnapshot.data will be set to initialData, unless a future has previously completed, in which case the previous result persists.
  • ConnectionState.done: In this state, future is not null and has completed. If the future completed successfully, the AsyncSnapshot.data will be set to the value to which the future completed. If it completed with an error, AsyncSnapshot.hasError will be true, and AsyncSnapshot.error will be set to the error object.

StreamBuilder Widget and FutureBuilder Widget have the same behavior: They listen to changes on their respective object. And trigger a new build when they are notified of a new value.

When to use FutureBuilder Widget?

Let’s say you want to fetch data from the backend on the launch of the page and show the loader till data comes.

Tasks for FutureBuilder:

  • Give the async task in the future of Future Builder.
  • Based on connectionState, show message (loading, active(streams), done)
  • Based on data(snapshot.hasError) show view

How to use FutureBuilder Widget in Flutter?

Consider the following code snippet to understand how to use it in a Flutter.

Create a Model class and it’s Constructor like a below:

class Job {
  final int? id;
  final String? position;
  final String? company;
  final String? description;

  Job({this.id, this.position, this.company, this.description});

  factory Job.fromJson(Map json) {
    return Job(
      id: json['id'],
      position: json['position'],
      company: json['company'],
      description: json['description'],
    );
  }
}

Now create a Stateless Widget like the below:

Our _fetchData() will have a code snippet a like below:

Future<List<Job>> _fetchData() async {
  final jobsListAPIUrl = 'https://mocki.io/v1/342919cc-1497-43b8-ac03-608b2330f440';
  final response = await http.get(jobsListAPIUrl);
  if (response.statusCode == 200) {
    List jsonResponse = json.decode(response.body);
    return jsonResponse.map((job) => new Job.fromJson(job)).toList();
  } else {
    throw Exception('Failed to load jobs from API');
  }
}

Our _jobsListView will look like below:

ListView _jobsListView(data) {
  return ListView.builder(
      itemCount: data.length,
      itemBuilder: (context, index) {
        return _tile(data[index].position, data[index].company, Icons.work);
      });
}

ListTile will look like below:

ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
       title: Text(title,
           style: TextStyle(
             fontWeight: FontWeight.w500,
             fontSize: 20,
           )),
       subtitle: Text(subtitle),
       leading: Icon(
         icon,
         color: Colors.blue[500],
       ),
     );

Just like a StreamBuilder Widget we will get data using the below code snippet.

List<Job> data = snapshot.data;

The complete Source code will look like below:

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

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: JobsListView(),
      ),
    );
  }
}


class Job {
  final int? id;
  final String? position;
  final String? company;
  final String? description;

  Job({this.id, this.position, this.company, this.description});

  factory Job.fromJson(Map json) {
    return Job(
      id: json['id'],
      position: json['position'],
      company: json['company'],
      description: json['description'],
    );
  }
}

class JobsListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder>(
      future: _fetchJobs(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          List? data = snapshot.data;
          return _jobsListView(data);
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }
        return CircularProgressIndicator();
      },
    );
  }

  Future> _fetchJobs() async {

    final jobsListAPIUrl = 'https://mocki.io/v1/342919cc-1497-43b8-ac03-608b2330f440';
    final response = await http.get(Uri.parse(jobsListAPIUrl));

    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      return jsonResponse.map((job) => new Job.fromJson(job)).toList();
    } else {
      throw Exception('Failed to load jobs from API');
    }
  }

  ListView _jobsListView(data) {
    return ListView.builder(
        itemCount: data.length,
        itemBuilder: (context, index) {
          return _tile(data[index].position, data[index].company, Icons.work);
        });
  }

  ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
        title: Text(title,
            style: TextStyle(
              fontWeight: FontWeight.w500,
              fontSize: 20,
            )),
        subtitle: Text(subtitle),
        leading: Icon(
          icon,
          color: Colors.blue[500],
        ),
      );
}

General Queries

  • Pros of FutureBuilder Widget

1. No two flags and no setState
2. Reactive programming FutureBuilder Widget will take care of updating the view on data arrival

Conclusion:

In this article, we have been through What is FutureBuilder Widget and how to use it in a Flutter.

That’s it for today.

Still, need support for Flutter Mobile Application? We Would love to assist you.

Develop You App Today

Nirali Patel

Written by Nirali Patel

Nirali Patel is a dedicated Flutter developer with over two years of experience, specializing in creating seamless mobile applications using Dart. With a passion for crafting user-centric solutions, Nirali combines technical proficiency with innovative thinking to push the boundaries of mobile app development.

Leave a comment

Your email address will not be published. Required fields are marked *

Discuss Your Project

Connect with Flutter Agency's proficient skilled team for your app development projects across different technologies. We'd love to hear from you! Fill out the form below to discuss your project.

Have Project For Us

Get in Touch

"*" indicates required fields

ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields