Return multiple value from function in dart - flutter

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}');

Related

Why changes made to this class field disappear after leaving async method?

So, I'm trying to do something that seems simple, but I can't get why it is not working.
I wrote this code:
class HomepageModel {
List<dynamic> data = [];
String _url = '[...]'; //My URL is working
Future _comm() async {
data = await httpFetch(_url); //This 'httpFetch' just does some json decoding
print(data); //Shows data normally
}
HomepageModel() {
_comm();
print(data); //Shows empty list
}
}
I want to store data retrieved from an API in the field data. I was able to get the data in function _comm, and when I print the field, it shows normally. But, outside this method, the content of the data field seems to have disappeared! Both on the print in the constructor, and in other files, all the prints show just an empty list.
What should I do to be able to properly store data from the API in a class field?
class HomepageModel {
List<dynamic> data = [];
String _url = '[...]'; //My URL is working
Future _comm() async {
data = await httpFetch(_url); //This 'httpFetch' just does some json decoding
print(data); //Shows data normally
}
HomepageModel() {
_comm().then((_){
print(data);
});
}
}

Problem while reading document from firestrore in flutter

I am new to Firebase I want to read all data of document here is how i am trying to read
This is my function to get data.
Future<List<AgencyModel>> getAgencyData() async {
List<AgencyModel> agencyListModel = [];
try {
agencyListModel = await _db.collection('colelctionName')
.doc('myDoc')
.snapshots()
.map((doc)=> AgencyModel.fromJson(doc.data()!)).toList();
print('List : ${agencyListModel.length}');
return agencyListModel;
} catch (e) {
debugPrint('Exception : $e');
rethrow;
}
}
This is how i am calling the above function
getAgencyDetails() async {
List<AgencyModel> data = await fireStoreService.getAgencyData();
print('Data : ${data.first}');}
and this is my models class fromjson function
factory AgencyModel.fromJson(Map<String, dynamic> json) {
return AgencyModel(
agencyName: json['agencyName'],
agencyContact: json['agencyContact'],
agencyAddress: json['agencyAddress'],
cnic: json['cnic'],
agencyContactDetails: json['agencyContactDetails'],
certificatesUrl: json['certificatesUrl'],
locationUrl: json['locationUrl'],
earning: json['earning'],
processing: json['processing'],
onHold: json['onHold']);}
I am not getting any error or exception, Also these two print statements does not work not display anything not even the Strings List : and Data : i.e
print('List : ${agencyListModel.length}');
print('Data : ${data.first}');}
UPDATE:
According to the documentation:
https://firebase.google.com/docs/firestore/query-data/get-data#dart_1
It is necessary to distinguish whether you want to retrieve the data only once or listen to changes over the document in real time.
It seems to me like you want to accomplish 1. case that you only want to retrieve data once. In that case.
You should change:
agencyListModel = await _db.collection('collectionName')
.doc('myDoc')
.snapshots()
agencyListModel = await _db.collection('collectionName')
.doc('myDoc')
.get()

Does compute support asnc request?

I have a list of String address like:
List<String> addressStrings = [....];
I am using geocoding plugin to get the address data and marker for these address strings like:
//This is a class-level function
Future<List<MarkerData>> getMarkerDataList() async {
List<MarkerData> list = [];
addressStrings.forEach((element) async {
final result = await locationFromAddress(element);
final markerData = MarkerData(element, result.first);
list.add(markerData);
});
return list;
}
But it freezes the UI as expected. I tried to use compute to perform the operation in another isolate like:
//This is a top-level function
Future<List<MarkerData>> getMarkerDataList(List<String> addressStrings) async {
List<MarkerData> list = [];
addressStrings.forEach((element) async {
final result = await locationFromAddress(element);
final markerData = MarkerData(element, result.first);
list.add(markerData);
});
return list;
}
//This is a class-level function
Future<List<MarkerData>> getMarkerData()async{
final result = await compute(getMarkerDataList, addressStrings);
return result;
}
But it doesn't work and shows Unhandled exception in the console.
I guess final result = await locationFromAddress(element); request is the problem here. Because it do pass before that statement but doesn't this one.
So, my question is: does compute support async? If yes, what I am doing wrong here? If no, how can I do asynchronous performance intensive tasks like this efficiently without blocking the UI?
Yes, as far as I know async does support compute - here's an article that should help out:
https://medium.com/flutterdevs/flutter-performance-optimization-17c99bb31553

Unable to use a Future value - Flutter/Dart

I've fetched a json object and deserialized it and then returned it too.
I want to use this in another file.
I'm unable to assign the values that I'm getting in the first step.
Here are all the codes...
Service
Future getGeoPoints(String accessToken, String tripId) async {
String requestUrl;
var response = await get(
Uri.parse(requestUrl),
headers: {
'Authorization': "Bearer $accessToken",
},
);
if (response.statusCode == 200) {
Map<String, dynamic> responseBody = json.decode(response.body);
GetGeoPoints geoPoints = GetGeoPoints.fromJson(responseBody);
List listOfGeoPoints = [];
for (var geoPoint in geoPoints.geoPoints) {
listOfGeoPoints.add(
{
'latitude': geoPoint.latitude,
'longitude': geoPoint.longitude,
'timestamp': geoPoint.timeStamp,
},
);
}
// print('List of geo points: ' + '$listOfGeoPoints');
return listOfGeoPoints;
} else {
throw Exception('Failed to load data from server');
}
}
File where I need the above values
List routeCoordinates;
Future<void> getValues() async {
getGeoPoints(widget.accessToken, widget.tripId)
.then((value) => routeCoordinates = value);
}
When I run the app, routeCoordinates is null but when I hotreload, it contains the value.
I want to have the values as soon as the screen starts. What is the right way to assign the values here?
I've also tried this:
routeCoordinates = getGeoPoints...
It throws error..
Please help.. Thanks..
The function getGeoPoints() is an asynchronous one. But on the other file, you are not using the await keyword, instead you are using then(). So your code is not waiting for that function to return value.
Try using below code,
List routeCoordinates;
Future<void> getValues() async {
routeCoordinates = await getGeoPoints(widget.accessToken, widget.tripId);
}
Let us know how it went.
You need to use a FutureBuilder to define a behaviour depending on the state of the request. You'll be able to tell the widget what to return while your app is waiting for the response to your request. You can also return a specific widget if you get an error(if your user is offline, for example).
Edit: I've linked the official docs but give this article a read if it's not clear enough.

Getting a map from Firestore and setting it to a new map

I have two methods the first one for getting a map stored in Firestore
Future daysMap(FirebaseUser user, String packageCode, int totalDays) async {
await users.document(user.uid).collection('myPackages')
.document(packageCode)
.get().then((doc){
// print(doc.data['DaysMap']);
return doc.data['DaysMap'];
});
}
It works correctly and prints out the map. The second method is for setting the map from Firestore to a new map in order to loop on it.
currentWorkout(FirebaseUser user, String packageCode,totalDays) async {
Map<dynamic, dynamic> days = await daysMap(user, packageCode, totalDays);
print(days);
}
When i print our the new map 'days' it always prints null.
Try using the async/await style.
Future daysMap(FirebaseUser user, String packageCode, int totalDays) async {
DocumentSnapshot doc = await users.document(user.uid).collection('myPackages').document(packageCode).get();
return doc.data['DaysMap'];
}