Reputation: 7735
I am having problems with futures in a Flutter app.
void saveCats() async {
var cats = await convertToCats(_rawData);
await DatabaseProvider.db.addCats(cats);
}
Future<List<Cat>> convertToCats(CatList catData) async {
var cats = <Cat>[];
await catData.forEach(key, value) async {
var pos = await calculatePos();
print('This should come first');
cats.add(Cat(name: key, pos: pos);
}
}
Future<int> calculatePos() async {
return await DatabaseProvider.db.calculatePos();
}
database.dart:
Future<void> addCats(List<Cat> cats) async {
print('This should come second');
// Do adding stuff here
}
Future<int> calculatePos() async {
// Some code to calculate the position
return pos;
}
In the above code, the saveCats
function is called when a button is tapped. This function converts some raw data to a list of Cat models, and adds them to the database. As part of this conversion process, it calculates the pos
of the cat in a list. My problem is that I would expect that, of my two print
statements, the one in the forEach
loop should come before the one in the addCats
database function. But instead they appear in reverse order. Where am I going wrong?
Upvotes: 0
Views: 686
Reputation: 51770
forEach
often doesn't do what you expect, because the provided function runs as a closure.
It's more natural when you want to iterate over a list doing something to each element to use for
(or one of the more functional type methods like map
).
It's not clear what type CatList
is, so this is approximate, but you'll want something more like:
Future<List<Cat>> convertToCats(CatList catData) async {
var cats = <Cat>[];
for (var i = 0; i < catData.length; i++) {
var key = catData[i].key;
var pos = await calculatePos();
print('This should come first');
cats.add(Cat(name: key, pos: pos));
}
return cats;
}
or
Future<List<Cat>> convertToCats(CatList catData) async {
return catData.map(...some mapping function...).toList();
}
Upvotes: 2
Reputation: 11941
You can't async/await
in List.forEach() or Map.forEach() as both of them return void.
Either use
await Future.forEach([1, 2, 3], (num) async {
await asyncMethod(num);
});
or something similar; https://api.flutter.dev/flutter/dart-async/Future/forEach.html
Upvotes: 3