Is there a difference whether using await with return in Dart? - flutter

In my flutter project, say there's a foo(int x) async function. And bar() async that looks like:
Future bar() async {
return foo(3);
}
The bar() function is just a simple capsule for foo(int x) with a certain parameter. And bar() is used as the future in a FutureBuilder.
I'm not sure if I should use await with return. I can't find related documentations online. So what's the difference between return foo(3) and return await foo(3)? Thank you!

No difference whatsoever.
Technically, using await first might wait for the Future to resolve before returning from the function, but you won't be able to tell the difference.
A Future is returned either way.
The async there is useless too, it might as well just be an arrow:
Future bar() => foo(3);
If it were not the last statement, and a return statement, this could matter, as pointed out in the comments, take the following:
Future bar() async {
try {
return await foo(3);
} catch(error) {
return baz;
}
}
If foo rejects, then it matters quite a lot, as it would be handled by the callee, not the caller.

Since you are returning Future, in this exact case, even if you don`t await it, the foo(3) will return Future instead and it is the exact thing your function wants to return. and if u await it there, then it will await in the function and then return the value.
you don`t even need await in this case if foo return Future. Then the caller of bar will instead await the bar.

Using this simple example you can see in which order prints yield:
Future<void> fetchUserOrder() {
return Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}
void main() async {
await fetchUserOrder();
print('Fetching user order...');
}
fetchUserOrder() returns Future. So if we call it in main with await, it will receive the Future, execute it and await for the result. Only then proceed to the second print of the main.
We could've written the fetchUserOrder() in such a fashion:
Future<void> fetchUserOrder() async {
return await Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}
And it wouldn't have had changed the result. It would work the same, the only difference is shorter code and that now you understand how it works.
Use https://dartpad.dev/ to launch these examples.

Related

Flutter Riverpod Future provider - requires async and await?

I've been reviewing the RiverPod 2 tutorial at https://codewithandrea.com/articles/flutter-state-management-riverpod/
In the section dealing with Future providers there is a code snippet as shown below...
final weatherFutureProvider = FutureProvider.autoDispose<Weather>((ref) {
// get repository from the provider below
final weatherRepository = ref.watch(weatherRepositoryProvider);
// call method that returns a Future<Weather>
return weatherRepository.getWeather(city: 'London');
});
I can't understand why this code snippet is missing the 'async' and 'await' syntax as shown below...
final weatherFutureProvider = FutureProvider.autoDispose<Weather>((ref) async {
// get repository from the provider below
final weatherRepository = ref.watch(weatherRepositoryProvider);
// call method that returns a Future<Weather>
return await weatherRepository.getWeather(city: 'London');
});
Is my version correct or what?
Think of it as doing:
Future<int> example() {
return Future.value(42);
}
instead of:
Future<int> example() async {
return await Future.value(42);
}
Sure, you can use async/await. But it is technically optional here.
Doing return future vs return await future doesn't change anything. In fact, there's a lint for removing the unnecessary await: unnecessary_await_in_return
The async keyword is generally helpful. It catches exceptions in the function and converts them into a Future.error.
But FutureProvider already takes care of that. So async could also be omitted

Run multiple asyn function flutter one after one flutter

hello I want have to run two functions(Function1() and Function2()) and store value of these returns and run third function. But some time according to condition Function1() or Function2() or both not be run.
if(condition1){
await Function1();
}
if(condition2){
await Function2();
}
await Functon3();
I try as above but Function3() run simultaneously with Function1() or with Function2().
My Function1() code looks like following...
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
If anything not clear please let me know in the comment section.
Please do not use .then() in combination with async/await. It is technically possible, but it takes some skill to get it right, so why make it hard on yourself. Stick with one way of doing it, use either one or the other. You mixed it up and through a slight oversight, your Function1 does not actually wait on it's result. It just returns, with the function still running in the then block. So you await it, but that does not help.
Since you are using await already, stick with that and remove .then() from your repertoire for now:
Future Function1() async {
try {
final value = await apiService.apiFileUpload();
///codes goes here
} catch(error) {
print('EEEE: ' + error.toString());
}
}
You can use await
Future Function1() async {
try{
final value = await apiService
.apiFileUpload();
final value2 = await secondFuntion();
///add more and condition on values
} catch(e){
.....
}
}
from your question you need to tell the compiler to stop on particular task with await and avoid using then function it will never stop your compiler
your future fuction:
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
Modified Future func
Future Function1() async {
var result = await apiService.apiFileUpload();
if(result == success){
// code goes here
}else{
//you can show your error here
}
}

Flutter Future<void> vs Future<Null> vs void

What is the main difference between:
Future<void> function(){}
Future<Null> function(){}
void function() {}
funtion(){}
Sometimes I use void or future when calling the API but I don't really know what the main difference is and when is the right time to use it?
Future<void> function() {}
Defines an asynchronous function that ultimately returns nothing but can notify callers when it eventually completes. Also see: What's the difference between returning void vs returning Future?
Future<Null> function() {}
Defines an asynchronous function that ultimately returns null when it eventually completes. Don't use this; this is an archaic form of Future<void>. It predates Dart 2 and was necessary because void was not yet a proper type, and there was no mechanism for indicating that a Future should return nothing. Also see: Dart 2: Legacy of the void
void function() {}
Defines a function that returns nothing. If the function does asynchronous work, callers will not be able to directly tell when it is complete.
function() {}
Defines a function with an unspecified return type. The return type is implicitly dynamic, which means that the function can return anything. Don't do this since it does not convey intent; readers will not be able to tell if the return type was omitted intentionally or accidentally. It also will trigger the always_declare_return_types lint. If you actually want to return a dynamic type, you should explicitly use dynamic function() {} instead.
By default, a function likes function() {} returns a null pointer value.
Use this archetype when your function not return anything and it's not marked as async:
function() { // <- not async
// ... some code
// ... don't use return
}
Optionally, you can specify not return values using void function() {} sintaxis. It's same at the function() {} but if you try to assign a value after calling you will get an error in compile time:
Error: This expression has type 'void' and can't be used.
Personally, i recommend this approach if you really don't have a return value and the function it's not async.
Note that you can use void in normal and async functions.
A function likes Future<void> function() async {} is for asynchronous function thats returns a Future<void> object.
I personally recommend the void function() async {} only if you don't use await ot then on call your function, otherwise, use Future <void> function() async {}.
An examples:
Future<void> myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
}
void main() async {
print(myFunction()); // This works and prints
// Instance of '_Future<void>'
// Hello
// Use this approach if you use this:
myFunction().then(() {
print('Then myFunction call ended');
})
// or this
await myFunction();
print('Then myFunction call ended');
}
void myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
}
void main() async {
print(myFunction()); // This not works
// The compile fails and show
// Error: This expression has type 'void' and can't be used.
// In this case you only can call myFunction like this
myFunction();
// This doesn't works (Compilation Error)
myFunction().then(() {
print('Then myFunction call ended');
});
// This doesn't works (Compilation Error)
await myFunction();
print('Then myFunction call ended');
}
A function likes Future<Null> function() async {} returns a Future<null> object. Use it whenever you return null. It's not recommended to use it because class Null not extends from Object and anything you return marks an error (except statements thats returns a null or explicit null value):
Future<Null> myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
// Ok
return (() => null)();
// Ok
return null;
}

Future<void> vs void

Say I want to create an asynchronous method. I can make its return type either Future void or simply "void" (as in examples below). Both ways seem to do the trick. So what's the difference between the two? When should I use Future void instead of void? Thanks!
Future<void> myMethod() async{
await myOtherMethod(); //myOtherMethod() has return type of Future<void>
print('something');
}
vs
void myMethod() async{
await myOtherMethod(); //myOtherMethod() has return type of Future<void>
print('something');
}
Use Future<void> where you want to
Call future functions:
myMethod().then((_) => ...).catchError((err) => ...);
Use await for more readable async code.
await myMethod();
await anotherMethod();
Use void where you want to fire and forget.
myMethod();
... do other stuff
The Future<void> is a lot more common. If you're not sure which one to use, use Future<void>.
Future<void> myMethod() async{ }
is a asynchronous function which means it let the app to work while waiting for some operation to finish(ex:Network Request).The Future fun(); is used while we need to perform operation that gives result in future such as network call.
void fun(){};
is function that doesnot return anything.

Calling two methods from a Future Either method, both with Future Either return type

I have these two methods:
Future<Either<Failure, WorkEntity>> getWorkEntity({int id})
and
Future<Either<Failure, WorkEntity>> updateWorkEntity({int id, DateTime executed})
They are both tested and work as expected. I then have this third method that combines the two:
Future<Either<Failure, WorkEntity>> call(Params params) async {
final workEntityEither = await repository.getWorkEntity(id: params.id);
return await workEntityEither.fold((failure) => Left(failure), (workEntity) => repository.updateWorkEntity(id: workEntity.id, executed: DateTime.now()));
}
This method does not work, it always return null. I suspect it is because I do not know what to return in the fold methods. How can this be made to work?
Thank you
Søren
The signature for the fold method is as follows:
fold<B>(B ifLeft(L l), B ifRight(R r)) → B
your ifLeft "Left(failure)" is returning an Either<Failure, WorkEntity> but ifRight "repository.updateWorkEntity(id: workEntity.id, executed: DateTime.now())" is returning a Future.
The easiest solution would be, as described here: How to extract Left or Right easily from Either type in Dart (Dartz)
Future<Either<Failure, WorkEntity>> call(Params params) async {
final workEntityEither = await repository.getWorkEntity(id: params.id);
if (workEntityEither.isRight()) {
// await is not needed here
return repository.updateWorkEntity(id: workEntityEither.getOrElse(null).id, executed: DateTime.now());
}
return Left(workEntityEither);
}
Also this might work (also untested):
return workEntityEither.fold((failure) async => Left(failure), (workEntity) => repository.updateWorkEntity(id: workEntity.id, executed: DateTime.now()));
Since I can not see any benefit in returning an exception I would just throw the exception and catch it with a try/catch block.