I'm still new to DART but I thought this would be easy to accomplish.
I want to check if a List from a future contains an integer. My return type is list dynamic but when I do the check it's telling me it's a Future.
The function that returns a List dynamic
I want to change the color of an icon
Icon(
Icons.favorite,
color: checkIfLiked(), // Change color here using a future.
size: buttonSize,
);
Future<List> userLikes() async {
GetUserLikes userLikesClicks = GetUserLikes();
Future<List> userLikes = userLikesClicks.getLikes();
List userList = await userLikes;
return userList; // returns List<dynamic>
}
I want to check of the Array contains an integer and if it does to return a color.
Future<Color> checkIfLiked() async{
Color color;
List resultUsersLikes = await userLikes();
if (resultUsersLikes.contains(widget.id)) {
color = Colors.blue;
} else {
color = Colors.grey;
}
return color;
}
I have to return a Color, and I am already using a FutureBuilder on the widget.
I need the color to change the color of an icon.
This is the icon
Icon(
Icons.favorite,
color: checkIfLiked(),
size: buttonSize,
);
How can I add an async here to await the future?
CodePudding user response:
as I see the userLikes()
is a Future
method, which means when you do this:
if (userLikes().contains(widget.id)) {
// ....
you're trying to call contains()
which belongs to the List
type on a Future
which didn't resolve yet to return the userList
from it.
what you need to do is to wait until it gets it and resolves, then use its result ( which will be a List
), like this:
Future<Color> checkIfLiked() async { // add async
List resultUsersLikes = await userLikes(); // then await for this
Color color;
if (resultUsersLikes.contains(widget.id)) { // then use it here
color = Colors.blue;
} else {
color = Colors.grey;
}
return color;
}
Now when you call checkIfLiked()
, first it will get the response from the userLikes()
then store it in resultUsersLikes
, then use it in the rest of your code :
and when you wanna use checkIfLiked()
in your other codes as the onPressed
of some button, you will need to await
for it to get its final response, like this:
onPressed: () async {
Color colorResult = await checkIfLiked();
}
You can set that color to the Icon
, by calling this method on initState
, then once it completes, update the state with the Color
, first declare a Color
variable in your State
class:
Color? resultColor;
then set it to your Icon
:
Icon(
Icons.favorite,
color: resultColor,
size: buttonSize,
);
then in your initState
:
@override
void initState() {
checkIfLiked().then((colorResponse) {
setState(() {
resultColor = colorResponse
});
});
}
now once the widget will be set inside the widget tree, the checkIfLiked()
will get called, when it finishes, the then
will be executed, which updates the state of resultColor
with the color got from the method.
CodePudding user response:
Like your error message states, The method 'contains' isn't defined for the type 'Future'. You should first await the future to resolve, and then you can use the List it returns. First of all, your checkIfLiked() function must return Future and inside it you should await userLikes() function.
Future<Color> checkIfLiked() async {
Color color;
if ((await userLikes()).contains(widget.id)) {
color = Colors.blue;
} else {
color = Colors.grey;
}
return color;
}
CodePudding user response:
Since you don't want checkIfLiked()
to return a Future<Color>
, you can try this
First declare a variable color and give it a default value.
Color color = Colors.grey;
Then call the below method checkIfLiked()
when you need to.
It will fetch the list of likes and finds the required color based on your logic.
Then it uses setState
to change the variable color's value from default value grey to required value.
Color change will happen automatically in all your widgets, where color
is referenced.
Future<void> checkIfLiked() async {
List userLikesList = await userLikes();
setState(() {
if (userLikesList.contains(widget.id)) {
color = Colors.blue;
} else {
color = Colors.grey;
}
});
}