Search code examples
dartasync-awaitdart-async

Dart async/await pattern explanation


I am trying to use the async/await pattern in my app because I don't like carrying Future's everywhere.

What I want to achieve is given this method:

Future<Map> loadConfig() {
  return Config.loadConfig().then((config) {
    // do some assertions in here
  });
}

and the caller:

void main() {
  Future<Map> config = loadConfig()
  .then((config) {
    // do complicated stuff, and have other async calls.    
    app.run(config);
  });
}

Is there a way I can use the async/await feature to make the code more pretty? I tried something like this:

Map loadConfig async () {
  Map config = await Config.loadConfig();
  // do some assertions on config
  return config;
}

and the caller:

void main() async {
  Map config = await loadConfig();
  // do complicated stuff, and have other async calls.    
  app.run(config);
}

and what it tells me in the loadConfig method is that type '_Future' is not a subtype of type 'Map' of 'function result'. as if the result of the await something() returns a Future<typeOfSomething>... isn't the point of all this to somewhat get rid the the Future and make it look like it's sync code?

As a side note, I am using

 ❯ dartanalyzer --version
dartanalyzer version 1.8.3

And for some reason it's not recognizing async and await keywords/syntax. Is there a switch to tell it to use the async features?

edit: maybe I'm doing something wrong but here's what I have tested after @Günter Zöchbauer's answer.

loadConfig() function:

Future<Map> loadConfig() {
  return Config.loadConfig().then((config) {
    assert(config["listeningPort"] != null);
    assert(config["gitWorkingDir"] != null);
    assert(config["clientPath"] != null);
    assert(config["websitePath"] != null);
    assert(config["serverPath"] != null);
    assert(config["serverFileName"] != null);
    assert(config["gitTarget"] != null);
    assert(config["clientHostname"] != null);
    print("Loaded config successfully");
  });
}

And my main caller function:

Map config = await loadConfig();
if (config == null) {
  print("config is null");
}
var patate = loadConfig().then((otherConfig) {
  if (otherConfig == null) {
    print("other config is null");
  }
});

which prints

Loaded config successfully
config is null
Loaded config successfully
other config is null

Any idea why?

edit2:

As pointed out by Gunter and Florian Loitsch, I had to write the loadConfig function like this:

Future<Map> loadConfig() {
  return Config.loadConfig().then((config) {
    assert(config["listeningPort"] != null);
    assert(config["gitWorkingDir"] != null);
    assert(config["clientPath"] != null);
    assert(config["websitePath"] != null);
    assert(config["serverPath"] != null);
    assert(config["serverFileName"] != null);
    assert(config["gitTarget"] != null);
    assert(config["clientHostname"] != null);
    print("Loaded config successfully");
    return config;
  });
}

Solution

  • You don't need to change the loadConfig function. The changes you applied to main() should do.