Getting values from Future instances

Hesh picture Hesh · Oct 5, 2017 · Viewed 24.6k times · Source

My data is something like this:

{
  "five": {
    "group": {
      "one": {
        "order": 2
      },
      "six": {
        "order": 1
      }
    },
    "name": "Filbert",
    "skill": "databases"
  },
  "four": {
    "group": {
      "three": {
        "order": 2
      },
      "two": {
        "order": 1
      }
    },
    "name": "Robert",
    "skill": "big data"
  },
  "one": {
    "name": "Bert",
    "skill": "data analysis"
  },
  "seven": {
    "name": "Colbert",
    "skill": "data fudging"
  },
  "six": {
    "name": "Ebert",
    "skill": "data loss"
  },
  "three": {
    "name": "Gilbert",
    "skill": "small data"
  },
  "two": {
    "name": "Albert",
    "skill": "non data"
  }
}

I am using the following function:

  Future retrieve(String id) async {
    Map employeeMap = await employeeById(id); //#1
    if (employeeMap.containsKey("group")) { //#2
      Map groupMap = employeeMap["group"];
      Map groupMapWithDetails = groupMembersWithDetails(groupMap); #3
      // above returns a Mamp with keys as expected but values 
      // are Future instances.
      // To extract values, the following function is
      // used with forEach on the map
      futureToVal(key, value) async { // #4
        groupMapWithDetails[key] = await value; 
      }
      groupMapWithDetails.forEach(futureToVal); // #4
    }
    return groupMapWithDetails;
   }
  1. I access an employee (as aMap) from the database (Firebase)
  2. If the employee is a leader (has a key "group")
  3. I get the details of each of the employee in the group filled up from the database by calling a separate function.
  4. Since the function returns a map with values that are instances of Future, I want to extract the actual values from them. For this a forEach is called on the map. However, I only get instances of Future as values.

How can I get the actual values?

Answer

Günter Zöchbauer picture Günter Zöchbauer · Oct 5, 2017

There is no way to get back from async execution to sync execution.

To get a value from a Future there are two ways

pass a callback to then(...)

theFuture.then((val) {
  print(val);
});

or use async/await for nicer syntax

Future foo() async {
  var val = await theFuture;
  print(val);
}