Chaing async method on Dart - flutter

I have following class.
class Element {
Future<Element> findById(var id)async {
await networkRequest();
return this;
}
Futute<Element> click() async {
await networkRequest();
return this;
}
}
I want to achieve the something like.
main() async {
var element = Element();
await element.findyById("something").click();
}
But I'm not able to do so because element.findById() returns future. How can I chain these async methods.

While there's no special syntax to chain futures, there are two semantically equivalent ways to do what you want:
1) Two separate await calls:
await element.findById("something");
await click();
2) Chaining with then:
await element.findById("something").then(() => click());

Use this,
await (await Element().findById("1")).click();

final el = await element.findyById("something");
await el.click();

Related

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, how to Future.wait numerous functions?

I know how Future.wait works
await Future.wait([
functionA(),
functionB()
]).then((data) {
});
but what I want to know is
What if the number of functions is not fixed and the number of functions to be called varies depending on the situation? (the functions are all the same.)
Elaborating on my comments, you can dynamically build a List of Futures and use Future.wait on that. For example:
Future<void> doAsynchronousStuff() async {
var waitList = <Future<void>>[];
if (someCondition) {
waitList.add(someAsynchronousFunction(someArgument));
}
if (someOtherCondition) {
waitList.add(someOtherAsynchronousFunction(someOtherArgument));
}
// ... and so on...
await Future.wait(waitList);
}
If you need to handle different return values from your asynchronous functions, you can use anonymous functions that set local variables. See Dart Future.wait for multiple futures and get back results of different types.
As long as you have an iterable reference, you can map that and return the Future function.
Future<void> main() async {
final List<int> resultFromApi = <int>[1, 2, 3, 4, 5];
final List<int> finalResult = await Future.wait(resultFromApi.map(
(int data) => complexProcess(data), // return the Future
));
print(finalResult);
}
Future<int> complexProcess(int data) async {
await Future<void>.delayed(const Duration(seconds: 1));
return data * 10;
}

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.

Dart: I made a function async but still can't use await

I made a function async but still can't use await expression. What am I wrong? My code is like this.
Future<void> _aFunction() async {
DocumentReference docRef = Firestore.instance.collection('collection').document(docId);
docRef.get().then((DocumentSnapshot docSnapShot) {
if (docSnapShot.exists) {
String ip = await Connectivity().getWifiIP();
That's because here is an internal (anonymous) function declaration inside then, which is not async. Actually, await keyword can be thought as a syntactic sugar over then, so it would be convenient to refactor the function like this:
Future<void> _aFunction() async {
final DocumentSnapshot snapshot = await Firestore.instance.collection('collection').document(docId).get();
if (snapshot.exists) {
String ip = await Connectivity().getWifiIP();
// Rest of the `ip` variable handling logic function
}
// Rest of the function
}
Now await keyword corresponds to the _aFunction itself instead of an anonymous function declared inside _aFunction, so it works as expected.

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();