Is there any difference between just returning a value and by using Future.value(); in Dart? - flutter

For example, is there any difference between those two code snippets? In dartpad, they return the same thing at the same time.
Does the function itself infer the returning value as bool from the function declaration (Future<bool>) so that using just 'return' is okay or is there any specific situation that make difference?
A:
Future<bool> anyFunction() async {
print('start');
var temp = Future.delayed(Duration(seconds: 5));
bool result = await getSomeResult();
print('end');
return result;
}
B:
Future<bool> anyFunction() async {
print('start');
var temp = Future.delayed(Duration(seconds: 5));
bool result = await getSomeResult();
print('end');
return Future<bool>.value(result);
}

Related

Flutter ensure I have a value in Async/Await and init functions [duplicate]

This question already has answers here:
What is a Future and how do I use it?
(6 answers)
Closed 20 days ago.
How can I make sure I have a state variable available after an async function call? My belief is because getValues() is async, it should "wait" until moving on to the next line. Thus, getValues() shouldn't exit and configValue() shouldn't be invoked until after my call to setState has finished. However the behavior I'm seeing it that values is an empty array in my Widget.
late List values = [];
#override
void initState() {
super.initState();
getValues();
configValue();
}
getValues() async {
final String response = await rootBundle.loadString('assets/values.json');
final vals = await json.decode(response)['values'];
setState(() {
values = vals;
});
}
void configValue() {
// How to make sure I have values[0] here?
}
Thanks in advance!
You can change your getValues to this:
Future<List> getValues() async {
final String response = await rootBundle.loadString('assets/values.json');
final vals = await json.decode(response)['values'];
return vals;
}
then create another middle function like this:
callasyncs() async {
var result = await getValues();
configValue(result);
}
and call it inside initState like this:
#override
void initState() {
super.initState();
callasyncs();
}
also change your configValue to this:
void configValue(List values) {
// now you have updated values here.
}
here your both configValue and getValues are separated from each other and also your configValue will wait for the getValues result.
you need to use await before the method to complete the future. also can be use .then.
Future<void> getVids() async { //I prefer retuning value
final String response = await rootBundle.loadString('assets/values.json');
final vals = await json.decode(response)['values'];
setState(() {
values = vals;
});
}
void configValue() async {
await getVids();
}
Try the following code:
List? values;
#override
void initState() {
super.initState();
getValues();
configValue();
}
Future<void> getVids() async {
final String response = await rootBundle.loadString('assets/values.json');
final vals = await json.decode(response)['values'];
setState(() {
values = vals;
});
}
void configValue() {
if (values != null) {
if (values!.isNotEmpty) {
…
}
}
}

type 'Future<List<Appointment>>' is not a subtype of type 'List<Appointment>' in type cast

The error should be clear but I'm unsure how to go around it.
Basically I have a Stream builder I'm calling every second by getData() method to update my SfCalendar with new data.
Stream<DataSource> getData() async* {
await Future.delayed(const Duration(seconds: 1)); //Mock delay
List<Appointment> appointments = foo() as List<Appointment>;
List<CalendarResource> resources = bar() as List<CalendarResource>;
DataSource data = DataSource(appointments, resources);
print("Fetched Data");
yield data;
}
But my appointments method foo() is of type Future<List> and not List.
Future<List<Appointment>> foo() async {
var url0 = Uri.https(
"uri",
"/profiles.json");
List<Appointment> appointments = [];
try {
final response = await dio.get(url0.toString());
//final Random random = Random();
//_colorCollection[random.nextInt(9)];
response.data.forEach((key, value) {
appointments.add(
Appointment(
id: int.parse(
value["id"],
),
startTime: DateTime.parse(value["startTime"]),
endTime: DateTime.parse(value["endTime"]),
),
);
});
} catch (error) {
print(error);
}
return appointments;
}
That is what the error should be telling, yes?
I tried removing the Future cast from foo() appointments but then I can't use async.
I also tried returning Future.value(appointments) but same error.
This is where I call my Stream in initState():
#override
void initState() {
super.initState();
print("Creating a sample stream...");
Stream<DataSource> stream = getData();
print("Created the stream");
stream.listen((data) {
print("DataReceived");
}, onDone: () {
print("Task Done");
}, onError: (error) {
print(error);
});
print("code controller is here");
}
Thank you, please help when possible
Just like JavaScript, async functions always return a Future. That's why you can't use async when you remove Future from the return type.
Since you're not waiting for that Future to resolve, you're actually trying to cast a Future to a List, which isn't a valid cast. All you should need to do is wait for the function to finish so it resolves to a List:
List<Appointment> appointments = await foo() as List<Appointment>;
and, since your return type is Future<List<Appointment>>, you don't actually need to cast the result.
List<Appointment> appointments = await foo();

Return String from a Future function

How can i return a string from a future function?
Future<String> functionA() async {
var x = await fetchX();
return x;
}
Future<String> fetchX() {
return Future.delayed(Duration(seconds: 4), () => 'example');
}
Future<String> la() async {
print(await functionA()); //this works correctly
return await functionA(); //this return always an instance of Future
}
How can i return "example" from the future function, there is a method to do it, and where is my error?
Future<String> fetch() async {
return
http.get('url')
.then((response) => response.body);
}
That way you can sneak a .catchError into there. :)
You need to specify what your function will return. All you have to do is add Future to the beginning of the method.
Future<String> fetch() async {
final response = await http.get('url');
String conteggio = response.body;
return conteggio;
}
And you have to do this in a method. You can only assign constant values in fields other than methods.

Is it possible to filter a List with a function that returns Future?

I have a list List<Item> list and a function Future<bool> myFilter(Item).
Is there a way to filter my list using the Future returning function myFilter()?
The idea is to be able to do something like this:
final result = list.where((item) => myFilter(item)).toList();
But this is not possible since where expects bool and not Future<bool>
Since the iteration involves async operation, you need to use a Future to perform the iteration.
final result = <Item>[];
await Future.forEach(list, (Item item) async {
if (await myFilter(item)) {
result.add(item);
}
});
You can iterate over your collection and asynchronously map your value to the nullable version of itself. In asyncMap method of Stream class you can call async methods and get an unwrapped Future value downstream.
final filteredList = await Stream.fromIterable(list).asyncMap((item) async {
if (await myFilter(item)) {
return item;
} else {
return null;
}
}).where((item) => item != null).toList()
You can try bellow:
1, Convert List => Stream:
example:
Stream.fromIterable([12, 23, 45, 40])
2, Create Future List with this function
Future<List<int>> whereAsync(Stream<int> stream) async {
List<int> results = [];
await for (var data in stream) {
bool valid = await myFilter(data);
if (valid) {
results.add(data);
}
}
return results;
}
Here's a complete solution to create a whereAsync() extension function using ideas from the accepted answer above. No need to convert to streams.
extension IterableExtension<E> on Iterable<E> {
Future<Iterable<E>> whereAsync(Future<bool> Function(E element) test) async {
final result = <E>[];
await Future.forEach(this, (E item) async {
if (await test(item)) {
result.add(item);
}
});
return result;
}
}
You can now use it in fluent-style on any iterable type. (Assume the function validate() is an async function defined elsewhere):
final validItems = await [1, 2, 3]
.map((i) => 'Test $i')
.whereAsync((s) async => await validate(s));
Try this:
final result = turnOffTime.map((item) {
if(myFilter(item)) {
return item;
}
}).toList();

In Dart, how to pass a function as parameter that returns a Future

I'm trying to pass as parameter of a method, a function that returns Future<Response>.
I tried to do
Future<String> _execute(Function<Future<Response>>() function) async { }
but it does not even compile.
What's the correct syntax?
You can do it like this,
Future<String> _myFunction(Future<Response> Function() function) {
...
}
You just need to specify that your parameter is a Function:
Future<bool> kappa() async{
await Future.delayed(Duration(seconds: 1));
return true;
}
​
Future<bool> foo(Function f) async{
var k = await f();
return k;
}
​
void main() async{
print(await foo(kappa));
}
This will print true. In your case, your function parameter can be:
Future<String> _execute(Function function) async { }