Dart: How to return Future<void> - android

How can I return Future<void> ?
Future<void> deleteAll(List stuff){
stuff.forEach( s => delete(s)); //How do I return Future<void> when loop and all delete Operation are finished?
}
Future<void> delete(Stuff s) async {
....
file.writeAsString(jsonEncode(...));
}
How do I return Future<void> when the forEach loop and all delete Operations are finished?

You don't need to return anything manually, since an async function will only return when the function is actually done, but it depends on how/if you wait for invocations you do in this function.
Looking at your examples you are missing the async keyword, which means you need to write the following instead:
Future<void> deleteAll(List stuff) async {
stuff.forEach( s => delete(s));
}
Future<void> delete(Stuff s) async {
....
await file.writeAsString(jsonEncode(...));
}
When using Future<void> there is no need to explicitly return anything, since void is nothing, as the name implies.
Also make sure you call deleteAll and writeAsString() using await.
Note: To wait for all delete/foreach invocations to complete, see below answer for more details. In short you will need to put all delete invocations in a Future.wait for that.

You can't do that with forEach.
But you can use Future.wait and .map like this
Future<void> deleteAll(List stuff) {
return Future.wait(stuff.map((s) => delete(s)));
}
Future<void> delete(Stuff s) async{
....
await file.writeAsString(jsonEncode(...));
}
When to use async keyword:
You can use async when your function uses await keyword inside.
So when to use await keyword:
when you want to get the result from an asynchronous function and want do some logic on the result
Future<int> fetchCountAndValidate() asycn{
final result = await fetchCountFromServer();
if(result == null)
return 0;
else
return result;
}
When you want to call multiple asynchronous function
Future<int> fetchTotalCount() asycn{
final result1 = await fetchCount1FromServer();
final result2 = await fetchCount2FromServer();
return result1 + result2;
}
When you don't need async or await:
When you just calling another asynchronous function
Future<int> getCount(){
//some synchronous logic
final requestBody = {
"countFor": "..."
};
return fetchCountFromServer(requestBody); //this is an asynchronous function which returns `Future<int>`
}
For some rare cases we doesn't care about the completion of asynchronous function
void sendLogoutSignal(){
http.post(url, {"username" : "id0001"});
}

Related

How do I get Future to wait for my transactions in Flutter

I have this Future and my code template like this:
Future getDevices() async {
stream.listen();
Timer.periodic(Duration(seconds:5), (timer) {
POST TO SERVER.then((value){
return Future.value(value);
});
});
}
I'm Listening to a Stream to scan for beacon devices.
I fill the yield named "beacons" in the Listen function of this Stream.
With Timer.periodic, I control the yield named "beacons" and perform POST operation. I want to return Future.value on "then" of this POST operation. But Future returns null without waiting for the result of POST operation.
I tried Completer like this:
Future getDevices() async {
final completer = Completer();
stream.listen();
Timer.periodic(Duration(seconds:5), (timer) {
POST TO SERVER.then((value){
return completer.complete(value);
});
});
return completer.future;
}
but this time I also got this error: "Unhandled Exception: Bad state: Future already completed"
EDIT:
I try to use Stream.asyncMap but same result when i did it.
Stream myStream = Stream.periodic(Duration(seconds: 5), (timer) async {
beacons.removeWhere((key, value) =>
DateTime.now().difference(value['lastUpdate']).inSeconds > 6);
if (beacons.isNotEmpty) {
bool processResult = false;
beacons.forEach((key, value) async {
if (int.parse(value['onlyEnterance'].toString()) == 1 &&
double.parse(value['distance'].toString()) <
double.parse(value['minDistance'].toString())) {
await userRepo
.createPayrollTracking(context, forEnter, value['dbId'])
.then((value) {
processResult = value;
if (value == true) {
stopMonitoring();
}
});
return await Future.value(processResult);
}
});
}
}).asyncMap((event) async => await event);

How to call one async function inside another async function in flutter

I have two future functions one for verifying OTP with API and another for setting a password using the API.
When the OTP verification is successful the set password API must be called. How can I do that?
My code is:
() async {
var status = await registrationService.verifyOtp(registrationData.mobileNumber,otpController.text);
if(status == 'approved'){
print('success');
() async {
var passwordStatus = await registrationService.setPassword(registrationData.name, registrationData.number, passController.text);
if(passwordStatus == 'approved'){
print('approved');
Navigator.pushNamed(context, StudMainPage.id);
}
else{
WidgetsBinding.instance.addPostFrameCallback((timeStamp) => _showNewVersionAvailableDialog(context));
}
};
}
}
It shows error or the function is not being called. What should I do now?
Thanks in advance.
Use then Callback
registrationService.verifyOtp(registrationData.mobileNumber,otpController.text).then((status) {
if(status == 'approved'){
print('success');
registrationService.setPassword(registrationData.name, registrationData.number, passController.text).then((response) {
//....
})))
}
Create a second async function for
Future<PasswordStatus> getPasswordStatus() async {
await registrationService.setPassword(registrationData.name, registrationData.number, passController.text);
}
and call that function as;
if(status == 'approved'){
var passwordStatus = await getPasswordStatus();
}
then just use the passwordStatus value.

Flutter how to get a Future<bool> to a normal bool type

Hi I'm trying to get a Future to be used as a normal boolean, how do I use this function as the determiner for a normal boolean without it giving me an incorrect type error?
Future<bool> checkIfOnAnyChats() async {
FirebaseUser user = await _auth.currentUser();
final QuerySnapshot result = await _firestore
.collection('chats')
.where('members', arrayContains: _username)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if(documents.length > 0) {
return Future<bool>.value(true);
}else{
return Future<bool>.value(false);
}
}
How do I apply it to a normal type boolean and not get this error? Thanks.
you don't need to convert bool into future, as you are in async method it will return future only.
you can get that value in initstate, you can not get value outside any method.
bool _isInChat;
#override
void initState() {
super.initState();
CheckIfOnAnyChats().then((value){
SetState((){
_isInChat = value;
});
});
}

setState() callback argument returned a Future in flutter

I'm trying to run a statment with await inside a setState block, I added it inside another Future<void> function but still I need to add async on the setState to be able to run it .
here is my code :
setState(() async {
chosenStations.clear();
chosenStations.add(allStations[
suggestions.indexOf(fromLocationName)]);
_loading = true;
chosenStations.add(allStations[
suggestions.indexOf(toLocationName)]);
await showingLines();
});
Future<void> showingLines() async {
theLines.clear();
theLines = await DatabaseServices().fetchingLinesData(
chosenStations[0], chosenStations[1]);
}
and I got this error :
Instead of performing asynchronous work inside a call to setState(), first execute the work (without updating the widget state), and then synchronously update the state inside a call to setState().
The error tells that you need to move all the asynchronous logic out of setState because setState used to update the UI after doing some work apart of its nature
so what you can do is to move the showingLines function out of setState and await it then update the UI with the new lines
await showingLines();
setState(() {
chosenStations.clear();
chosenStations.add(allStations[
suggestions.indexOf(fromLocationName)]);
_loading = true;
chosenStations.add(allStations[
suggestions.indexOf(toLocationName)]);
});
Future<void> showingLines() async {
theLines.clear();
theLines = await DatabaseServices().fetchingLinesData(
chosenStations[0], chosenStations[1]);
}
Note: you can use setState directly without filling it with any work,
await showingLines();
chosenStations.clear();
chosenStations.add(allStations[
suggestions.indexOf(fromLocationName)]);
_loading = true;
chosenStations.add(allStations[
suggestions.indexOf(toLocationName)]);
setState(() {});
Future<void> showingLines() async {
theLines.clear();
theLines = await DatabaseServices().fetchingLinesData(
chosenStations[0], chosenStations[1]);
}

async and await in flutter

In my flutter app, the async function runs at last, but according to the code, it should run after the print start and before the print end.
#override
void initState() {
super.initState();
print('start');
getApiData();
print('end');
}
void getApiData() async {
HomePageNetworking homePageNetworking = HomePageNetworking();
var apiIndiaData = await homePageNetworking.getDataIndia();
print(apiIndiaData);
}
Please help me fix this issue.
Try that:
Put all of them in an async function and call the function in the initstate.

Categories

Resources