Issues with flutter futures - map results in List<Future>

Viewed 33

I'm having issues with the return type of this HTTP request, I need to return Future<List> but the map is returning a List<Future>. I don't know how to get the CustomerInfo without it being a future and I don't know how to return it any other way.

    if (response.statusCode == 200) {
      Iterable l = json.decode(response.body);
      final data = List.from(l.map((model) async {
        final name = model['UserName'];
        final id = model['UserICode'];
        return {name, id};
      }));
      final users =  data.map<CustomerInfo>((e) async {return await getFaxinfo(e.id, e.name);});
      return users;
    } else {
      throw 'err';
    }
  }

  Future<CustomerInfo> getFaxinfo(
    String id,
    String name,
  ) async {
    final baseUrl = 'localhost';
    final int port = 3003;
    final accountsPath = '/accounts';
    final accountsFaxInfoPath = '$accountsPath/fax-info';

    final Map<String, dynamic> queryParam = {'id': id};
    final uri = Uri(
        scheme: 'http',
        path: accountsFaxInfoPath,
        host: baseUrl,
        queryParameters: queryParam);
    final response = await http.get(uri);
    return CustomerInfo(sent: 200, received: 300, name: 'Test');
  }
1 Answers

The problem is that an async function always returns a Future no matter if you call await inside it or not. To fix it a good approach is to use list comprehension. A simple for loop also would do.

Instead of those 2 maps that result in List<Future>:

final data = List.from(l.map((model) async {
  final name = model['UserName'];
  final id = model['UserICode'];
  return {name, id};
}));
final users = data.map<CustomerInfo>((e) async {return await getFaxinfo(e.id, e.name);});

Do the following with list comprehension:

final users = [
  for (final model in l)
    await getFaxinfo(model['UserICode'], model['UserName'])
];

Now if you want to make the HTTP calls in parallel it's possible to do a Future.wait() in a List<Future> to get the result as List<CustomerInfo>. Something like the following:

final users = await Future.wait(l.map((model) async =>
    await getFaxinfo(model['UserICode'], model['UserName'])));
Related