
Theory Behind Flutter Future Builder
Flutter Future Builder as the name suggests it’s a builder which will build a widget once the future is resolved. In other words, it will help you to build other widgets with the data that will come from API calls(Future).
FutureBuilder(
future: _getPlaces, //Future to be resolved
builder: (Buildcontext context, AsyncSnapshot<DataModel> model) {
if(model.hasData){
return SomeWidget(model.data); //Passing data to the widget
}
return CircularProgressionBar(); //While data is being loaded this will show up
}
),
The code mentioned above is the syntax of Flutter Future Builder. let’s break it down :
future(Argument): This argument takes a future variable that needs to be resolved. Or you can say this is the part of code that will help us to get data while building our application.
builder(Method): This method helps us to build our UI in response to the data collected from the future. This builder takes in 2 parameters (1: BuildContext & 2:Type of data that our future will return). After that, we are just checking if there is some data in the model. If yes then we are returning a widget that will build our data. As you know API’s might take some time to fetch till then a default CircularProgressionBar will be loaded.
Use Cases
Future Builder is used whenever we need to fetch data dynamically from the database and update that on the runtime. Below is a chart that will help us understand how it actually works.

Let’s build a real-world news application using flutter future builder
Before starting you need to make sure that you have installed flutter on your machine. We are not going to cover the installation part but if you want to check how to install you can follow this blog -> Install Flutter
First, we need to install a package in our pubspec.yamal file
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
Please note at the time of writing the blog this was the latest http package but you can install the latest package from pub.dev
After that, we need to create 4 files in our lib folder
- newsModel.dart // This file will help you in storing api’s response
- apiService.dart // This file will help you in calling api’s json data
- newsBuilder.dart // This file will help us build the actual news widget which the user will see
- home.dart // This file will be our landing page for the application where we will call other files to display news
Now let’s start coding! Head over to your main.dart
import 'package:flutter/material.dart';
import 'package:news/home.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'News Example App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
We are just defining our landing page in main.dart
Now let’s create a model class to store the API’s response
class NewsModel {
String name;
String url;
String desc;
String image;
NewsModel(
{required this.desc,
required this.image,
required this.name,
required this.url});
}
let’s create a get API call
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:news/newsModel.dart';
class ApiCall {
Future<List<NewsModel>> getNews() async {
List<NewsModel> news = <NewsModel>[];
Uri url = Uri.parse(
"https://newsapi.org/v2/everything?q=tesla&apiKey=3d358e1e8a2e46f798d439ae6be556e1");
var response = await http.get(url);
if (response.statusCode == 200) {
print("Success");
var data = jsonDecode(response.body);
data["articles"].forEach((element) {
if (element['urlToImage'] != null && element['description'] != null) {
NewsModel article = NewsModel(
desc: element['description'],
image: element['urlToImage'],
name: element['title'],
url: element["url"],
);
news.add(article);
}
});
return news;
}
throw response.statusCode;
}
}
create home.dart
import 'package:flutter/material.dart';
import 'package:news/apiCall.dart';
import 'package:news/newsBuilder.dart';
import 'package:news/newsModel.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
ApiCall apiCall = ApiCall();
late Future<List<NewsModel>> getnews;
@override
void initState() {
getnews = apiCall.getNews();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffDBDBDB),
appBar: AppBar(
title: Text("Flutter Future Builder"),
),
body: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
top: 10.0, left: 20.0, right: 20.0, bottom: 70.0),
child: Container(
child: FutureBuilder(
future: getnews,
builder: (BuildContext context,
AsyncSnapshot<List<NewsModel>> snapshot) {
if (snapshot.hasData) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data!.length,
physics: ClampingScrollPhysics(),
itemBuilder: (context, index) {
return NewBuilder(
desc: snapshot.data![index].desc,
image: snapshot.data![index].image,
name: snapshot.data![index].name,
url: snapshot.data![index].url,
);
},
),
);
}
return Center(child: CircularProgressIndicator());
},
),
),
),
],
),
),
);
}
}
News Builder
import 'package:flutter/material.dart';
class NewBuilder extends StatefulWidget {
const NewBuilder(
{Key? key,
required this.name,
required this.url,
required this.desc,
required this.image})
: super(key: key);
final String name;
final String url;
final String desc;
final String image;
@override
_NewBuilderState createState() => _NewBuilderState();
}
class _NewBuilderState extends State<NewBuilder> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Stack(
children: [
Container(
height: 200.0,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.black38, blurRadius: 1.5)],
borderRadius: BorderRadius.circular(12.0),
),
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
height: 150.0,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(12),
topLeft: Radius.circular(12),
),
image: DecorationImage(
image: NetworkImage("${widget.image}"),
fit: BoxFit.cover),
),
),
),
Positioned(
bottom: 0,
child: Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: Text("${widget.name}"),
),
),
],
));
}
}