In the code provided the print function returns the correct number of friends that should be printed, but when I try to return it, it returns (Instance of Future ) and does not return the real value (the number)
Future<int> FriendsNumber() async {
final count = await _firestore
.collection('FriendsList')
.doc(User.userID)
.collection("FriendsList")
.where("Status", isEqualTo: 1)
.get()
.then((res) => res.size);
print('number of friends is:');
print(count);
return count;
}
return Scaffold(
body: Column(
children: [
Text(
FriendsNumber().toString();
),
],
),
);
CodePudding user response:
You have to use future builder for this
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder<int>(
future: FriendsNumber(),
builder: (BuildContext context, snapshot) {
if (!snapshot.hasData) {
// while data is loading:
return Center(
child: CircularProgressIndicator(),
);
} else {
// data loaded:
final friendNumber= snapshot.data;
return Center(
child: Text('Friends are: $friendNumber'),
);
}
},
),
),
);
}
}
CodePudding user response:
That is how async
and await
works in Dart. await
allows asynchronous functions to have the appearance of synchronous functions by allowing asynchronous code to be executed very similarly to synchronous code. This line in your code defers further execution of this function until the result of the firestore query is returned:
final count = await _firestore
.collection('FriendsList')
.doc(User.userID)
.collection("FriendsList")
.where("Status", isEqualTo: 1)
.get()
.then((res) => res.size);
Since dart is not blocking here it has to return some value, which in this case is a Future<int>
, which bascially means that in the Future
this will be resolved to an int
value.
Your print statement is after the await
(where the execution will pick up again when the result from firestore got returned) and thus can use value directly.
CodePudding user response:
You can not extract the value of a Future without using a FutureBuilder widget.
If this is a data that you will need only once and it will not change you can call your Future method inside the initState() method like that :
@override
void initState() {
super.initState();
FriendsNumber().then((value) {
setState(() {
count = value; //here you can continue your filter logic, ex: value.contains etc...
});
});
}
Doing so will allow you to display the data like you show in your post.
return Scaffold(
body: Column(
children: [
Text(
count.toString();
),
],
),
);