larryq
larryq

Reputation: 16309

How to make a nested httpClient call, multiple async / awaits in Dart

I have to make a few calls using httpClient. One of them gets the 'main' data for a given blog post in json format, and with that info I then have to make a second call for additional media info related to that post.

This is all for multiple posts, so in essence I'm doing:

Future<List<String>> fetchPosts() async {
  response = await httpClient.get('http://somewebsite/topPosts');
  data = json.decode(response.body) as List;
  data.map((singlePost) {
    mediaID = singlePost["mediaID"];
    //second await call below, this won't work as-is, correct?
    finalData = await httpClient.get('http://somewebsite/media/$mediaID')

I hope that makes sense, what I'm trying accomplish. Essentially I'm nesting http calls. Not sure of a 'good' way of doing this, maybe something with Future.wait(), any advice welcome.

Upvotes: 0

Views: 66

Answers (1)

jamesdlin
jamesdlin

Reputation: 90155

 data.map((singlePost) {
    mediaID = singlePost["mediaID"];
    //second await call below, this won't work as-is, correct?
    finalData = await httpClient.get('http://somewebsite/media/$mediaID')

Isn't going to work. First, you're using await in the callback supplied to map, but await can be used only in a function marked async.

After you mark the callback with async, the code probably doesn't do what you want. List.map() is used to transform a List. For example, you'd use it to create a list of Strings from a list of ints or vice-versa. In this case, you'll be generating a list (actually an Iterable) of Futures. You don't store that list of Futures anywhere, and therefore you can't ever await them to be notified when they complete.

What you might is something like:

final futures = data.map((singlePost) async { ... });
await Future.wait(futures);

And that would wait for all operations to complete. However, you'll have another problem in that your map callback does:

finalData = await httpClient.get('http://somewebsite/media/$mediaID')

which means that each callback will clobber the finalData variable (whatever that is) in some unspecified order.

Upvotes: 1

Related Questions