Flutter - Retrieve value in getter outside of a .then() function - flutter

I´ve created a get method outside the Widget tree to retrieve a value from a database provider. But the problem: Because it is a Future type I have to get this data with .then() ..and outside of .then() my return does not know this value.
Example:
String get _plannedHours {
final calendarEntriesData =
Provider.of<CalendarEntries>(context, listen: false);
calendarEntriesData.getPlannedHoursFromMonth(_currentDate).then((value) {
print(value.length); // I need this value
});
return "Value: 20"; // ....here!
}
How I get this value outside of .then() to return a value to the Widget three?

You can use async/await to access the value:
Future<String> get _plannedHours async {
final calendarEntriesData =
Provider.of<CalendarEntries>(context, listen: false);
var value = await calendarEntriesData.getPlannedHoursFromMonth(_currentDate);
return "Value: ${value.length}";
}
Then you need to do:
await _plannedHours

Related

Return multiple value from function in dart

Hi so i'm new to dart and I'm having an issue with returning 2 value from a dart function.
Currently I have this function :
Future LoadAllData({required Map data, required String detailId}) async {
loadUserData(data: data);
powData = await Database.getPowDataActive(detailId: detailId);
return powData;
}
so getPowDataActive is a function that will fetch a data from my database and it will return some map data, load user data will also fetch data and will also return some map. I wanted to use the loadAllData function for my futureBuilder and use the snapshot data from this 2 function for different purposes, can I do so ? or I have to first combine the return from both function into 1 variable and access it differently ?
Thanks before
You can create a model like this:
class LoadDataResult {
final Map userData;
final Map powData;
LoadDataResult({#requierd this.userData, #requierd this.powData, });
}
and then use it like this:
Future<LoadDataResult> LoadAllData({required Map data, required String detailId}) async {
var userData = await loadUserData(data: data);
powData = await Database.getPowDataActive(detailId: detailId);
return LoadDataResult(userData:userData, powData: powData);
}
and then use it like this in futureBuilder:
LoadDataResult data = snapshot.data;
print('${data. userData}');

Flutter - await/async on a List - why does this only work when not using declarations?

Still new to Flutter :(. Can anyone help...
I have a class that stores a bunch of project information. One part of this is a list of topics (for push notification), which it grabs from a JSON file.
I apply a getter for the list of topics, and when getting it it calls an async function which will return a List
Future<List<String>> _pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return (jsonDecode(_json.body));
}else {
return [""];
}
}
Future<List<String>> get topics => _pntopics();
In my main.dart file, it calls this value like so...
Future<List<String>> _topiclist = await projectvalues.topics;
The response is however empty, pressumably because it is a Future - so it is grabbing the empty value before it is filled.
But I can't remove the "Future" part from the async method, because asnc methods require a Future definition.
Then I decided to remove the declarations entirely:
_pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return (jsonDecode(_json.body));
}else {
return [""];
}
}
get topics => _pntopics();
and in main.dart, a general declaration...
var _topiclist = await projectvalues.topics;
...and this works!
So what declaration should I actually be using for this to work? I'm happy to not use declarations but we're always to declare everthing.
You should return back Future<List<String>> return types to the function and the getter but for _topicslist you must use var, final or List<String> declaration because:
(await Future<T>) == T
i.e.
var _topiclist = await projectvalues.topics; // The type of _topiclist is List<String>
final _topiclist = await projectvalues.topics; // The type of _topiclist is List<String>
UPDATE
Your code should be:
Future<List<String>> _pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return List<String>.from(jsonDecode(_json.body));
}else {
return <String>[""];
}
}
Doing this you force _pnptopics returns List<String> as jsonDecode returns List<dynamic>.
P.S. It is good practice do not use dynamic types where they can be changed to specified types.

How can I return a Future from a stream listen callback?

I have below code in flutter:
getData() {
final linksStream = getLinksStream().listen((String uri) async {
return uri;
});
}
In getData method, I want to return the value of uri which is from a stream listener. Since this value is generated at a later time, I am thinking to response a Future object in getData method. But I don't know how I can pass the uri as the value of Future.
In javascript, I can simply create a promise and resolve the value uri. How can I achieve it in dart?
In your code 'return uri' is not returning from getData but returning from anonymous function which is parameter of listen.
Correct code is like:
Future<String> getData() {
final Completer<String> c = new Completer<String>();
final linksStream = getLinksStream().listen((String uri) {
c.complete(uri);
});
return c.future;
}
Try this
Future<String> getData() async{
final linksStream = await getLinksStream().toList();
return linksStream[0].toString();
}

How can we get value from future method in flutter?

I have this function returning the "SharedPreference" value stored in it.
Future<bool> getLoginStatus() async {
final prefs = await SharedPreferences.getInstance();
final loggedInStatus = prefs.getBool("loggedInStatus");
if (loggedInStatus == null) {
return false;
}
return loggedInStatus;
}
Above function is in the class named "Constants.dart". When I do the test of extracting value from "getLoginStatus()" function by simple printing in different class.
print("Login status : " + Constants().getLoginStatus().toString());
It give me below as an output. Why "Instance of 'Future'"? Why not simple either true or false?
I/flutter (19683): Login status : Instance of 'Future<bool>'
Since your getLoginStatus() is asynchronous and it return a bool value in future. So to get the value you have to await for the process to return it.
So the correct Code to retrieve the value would be :
bool loggedInStatus = await Constants().getLoginStatus();
print(loggedInStatus);
getLoginStatus().then((val){ print("Login status : $val"});
The then function should be used with Futures to access the value returned from a future.
you can get data using await.
var data = await Constants().getLoginStatus();
print(data);

Why does this Flutter example not have a return keyword?

I am reading over the documentation for Flutter.
On this page, I have observed the following curious method. In the method, the declared return type is Future. The method though, does not have the return keyword present anywhere. Why is this?
Future<void> _incrementCounter() async {
setState(() {
_counter++;
});
Directory directory = await getApplicationDocumentsDirectory();
final String dirName = directory.path;
await File('$dir/counter.txt').writeAsString('$_counter');
}
I have been able to ascertain that all flutter functions return a value, and the default return value is null. But if this method always returns null, then why declare a return type of Future<void>?
That is because the function is marked with the async modifier:
Future foo() async {
print('hello world');
}
is equivalent to
Future foo() {
try {
print('hello world');
return Future.value(null);
} catch (err) {
return Future.error(err);
}
}
In Dart even-though it's an optionally typed language which means you can omit the type , It's recommended to provide it
When method does not have a return type , return null is appended , So in your example it's fit to return Future.value(null);
please see Default return type in Dart