Flutter: Future Builder with List View Builder

1. What are Future Operations?

Future operations are the operations which take time to perform and return the result later. To handle this problem, we use Asynchronous functions.

2. Asynchronous Functions

Asynchronous operations let your program continue other operations while the current operation is being performed. Dart uses Future objects (futures) 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. So it is quite tricky to handle futures in widgets. To solve this problem flutter provided a widget called Future Builder.

3. Future Builder

In future builder, it 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.

class ProjectModel {
String id;
String createdOn;
String lastModifiedOn;
String title;
String description;

ProjectModel({
this.id,
this.createdOn,
this.lastModifiedOn,
this.title,
this.description,
});
}

I have created a model “ProjectModel”. In the below example, I have used the future builder and for a list, I have used List view builder. In the example, I have created an array of “projects” and an empty list “projectList”, you can get a list of the projects through the API, and call that API in a future function.

Example of future function:Future getProjectDetails() async {
List<ProjectModel> projetcList = await someFutureCall();
return projetcList;
}

In the above example, I have assigned the array of projects to the list, you can call API.for example

Future getProjectDetails() async {
var result = await http.get('https://getProjectList');
return result;
}

Implement the widget to display the list of projects with the future builder.

Widget projectWidget() {
return FutureBuilder(
builder: (context, projectSnap) {
if (projectSnap.connectionState == ConnectionState.none &&
projectSnap.hasData == null) {
//print('project snapshot data is: ${projectSnap.data}');
return Container();
}
return ListView.builder(
itemCount: projectSnap.data.length,
itemBuilder: (context, index) {
ProjectModel project = projectSnap.data[index];
return Column(
children: <Widget>[
// Widget to display the list of project
],
);
},
);
},
future: getProjectDetails(),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ProjectList'),
),
body: projectWidget(),
);
}

In my example, the future function `getProjectDetails()` is called in the future. As soon as the result appears, it calls the builder. The builder has two parameters context and asyncSnapshot.

AsyncSnapshot has 3 state:

  1. 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.
  2. connectionState.waiting = [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.
  3. connectionState.done = [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.

Leave a Comment

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