How to get data from async function to show on a widget.
This article is about a very useful widget of Flutter, the Future builder widget.
When you want to show some async
function result on a widget you will face some troubles because a widget’s build sync
method will not wait while fetching data. Flutter provides a better answer to this question. It is the Future Builder widget.
This is the asynchronous function I used to explain how the Future Builder widget works. This function simply returns a String object.
Future<String> getUserName(int userID) async {
String userName = await DatabaseService().getUserName(userID); return userName;
}
The below codes show a builder function and how we can use the Future Builder widget to show the data returns by the above code.
Method 1 (using connection states)
Widget build(BuildContext context) {
return FutureBuilder(
future: getUserName(1),
builder: (BuildContext context, AsyncSnapshot<String> userNameSnapshot) {
Widget widget;
if (userNameSnapshot.connectionState == ConnectionState.done) {
widget = Text(userNameSnapshot.data)
} else {
widget = Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(),
),
);
}
return widget;
},
);
}
In this example, the future function getUserName()
is called in the future. When this method returns data, the userNameSnapshot
object’s connection state will be equal to ConnectionState.done
and the builder will return the text widget.
There are three connection states of AsyncSnapshot
.
ConnectionState.none
— Not currently connected to any asynchronous computation. For example, a FutureBuilder whose FutureBuilder.future is null.ConnectionState.waiting
— Connected to an asynchronous computation and awaiting interaction.ConnectionState.done
— Connected to a terminated asynchronous computation.
Here I showed one way of handling async
function results using the Future Builder widget. There is another method to handle this using the states(hasData
and hasError
) of AsyncSnapshot
.
Method 2 (using hasData
and hasError
states)
We can use hasData
and hasError
states of AsyncSnapsot
to handle the Future Builder widget.
Widget build(BuildContext context) {
return FutureBuilder(
future: getUserName(1),
builder: (BuildContext context, AsyncSnapshot<String> userNameSnapshot) {
Widget widget;
if (userNameSnapshot.hasData) {
widget = Text(userNameSnapshot.data)
} else if(userNameSnapshot.hasError){
widget = Text('Error: ${userNameSnapshot.error}')
} else {
widget = Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(),
),
);
}
return widget;
},
);
}
basically userNameSnapshot.hasData
returns true when AsyncSnapshot
is with data and otherwise, it returns false, userNameSnapshot.hasError
returns true when AsyncSnapsho
is with error(s) or else it returns false.
Likewise, we can use these two methods to show async
function results on widgets.