I'm trying to create a class that calls an api to retrieve a word's definition.

I'm obviously missing something as my output is not in the expected ordering:

  • Expected Ordering: start, Try, 2
  • Actual Ordering: start, Try, No definition available, 2

So obviously its not actually awaiting. I've tried a few variations but cant seem to get it right.

I should note that this class will be used as part of a flutter app, so i want to enscapulate the await inside the class itself if thats possible.

import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'dart:convert';
import 'dart:developer' as devtools show log;

class WordDefintion {
  String word;
  List<dynamic>? meanings;
  int? meaningsCount;
  // bool hasDefinition;

  static String freeDictionaryUrl = 'api.dictionaryapi.dev';

  WordDefintion.fromFreeDictionary(this.word) {
    Future<List<dynamic>> retrieveFreeDefinition(word) async {
      final client = RetryClient(http.Client());
      try {
        var response = await client
            .read(Uri.https(freeDictionaryUrl, '/api/v2/entries/en/$word'));
        return jsonDecode(response);
      } finally {
        client.close();
      }
    }

    try {
      print('Try');
      retrieveFreeDefinition(word).then((responseJson) {
        print(responseJson.length);
        meanings = responseJson[0]['meanings'];
        meaningsCount = responseJson[0]['meanings'].length;
      });
    } catch (e) {
      print(e.toString());
      print('Failed ');
      // hasDefinition = false;
      meanings = null;
      meaningsCount = null;
    }
  }

  @override
  String toString() {
    if (meanings != null) {
      String outString = '$meanings meanings found:';
      for (var meaning in meanings!) {
        var partOfSpeech = meaning['partOfSpeech'];
        for (var definition in meaning['definitions']) {
          outString +=
              "PartOfSpeech: '$partOfSpeech' Meaning: '$definition['definition']'\n";
        }
      }

      return outString;
    } else {
      return 'No definition available.';
    }
  }
}
main() async {
  print('start');

  var wordDefinition = WordDefintion.fromFreeDictionary("ground");

  print(wordDefinition.toString());
}


Solution 1: Kaushik Chandru

By adding then in future doesn't wait for the future to complete but instead execute the next command and then execute the codes that inside the then later on.. You can try the following

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'dart:convert';
import 'dart:developer' as devtools show log;

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

main() async {
  print('start');
  WordDefintion _wordDefinition = WordDefintion();
  var wordDefinition = await _wordDefinition.fromFreeDictionary("ground");

  print(wordDefinition.toString());
}

class WordDefintion {
  List<dynamic>? meanings;
  int? meaningsCount;
  // bool hasDefinition;

  static String freeDictionaryUrl = 'api.dictionaryapi.dev';

  Future<String> fromFreeDictionary(word) async {
    Future<List<dynamic>> retrieveFreeDefinition(word) async {
      final client = RetryClient(http.Client());
      try {
        var response = await client
            .read(Uri.https(freeDictionaryUrl, '/api/v2/entries/en/$word'));
        return jsonDecode(response);
      } finally {
        client.close();
      }
    }

    try {
      print('Try');
      var responseJson = await retrieveFreeDefinition(word); //<--here it will wait for the future to finish

      print(responseJson.length);
      meanings = responseJson[0]['meanings'];
      meaningsCount = responseJson[0]['meanings'].length;
      String outString = '$meanings meanings found:';
      for (var meaning in meanings!) {
        var partOfSpeech = meaning['partOfSpeech'];
        for (var definition in meaning['definitions']) {
          outString +=
              "PartOfSpeech: '$partOfSpeech' Meaning: '$definition['definition']'\n";
        }
      }
      return outString; <--here it will return after the result is fetched and converted
    } catch (e) {
      print(e.toString());
      print('Failed ');
      // hasDefinition = false;
      meanings = null;
      meaningsCount = null;
      return Future.value('No definition available.');//<--here it will return no definition
    }
  }
}

Output

start
Try
2
[{partOfSpeech: noun, definitions: [{definition: The surface of the Earth, as opposed to the sky or water or underground., synonyms: [], antonyms: [], example: Look, I found a ten dollar bill on the ground!}, {definition: Terrain., synonyms: [], antonyms: []}, {definition: Soil, earth., synonyms: [], antonyms: [], example: The fox escaped from the hounds by going to ground.}, {definition: The bottom of a body of water., synonyms: [], antonyms: []}, {definition: Basis, foundation, groundwork, legwork., synonyms: [], antonyms: []}, {definition: (chiefly in the plural) Reason, (epistemic) justification, cause., synonyms: [], antonyms: [], example: He could not come on grounds of health, or on health grounds.}, {definition: Background, context, framework, surroundings., synonyms: [], antonyms: []}, {definition: The area on which a battle is fought, particularly as referring to the area occupied by one side or the other. Often, according to the eventualities, "to give ground" or "to gain ground"., synonyms: [], antonyms: []}, {definition: (by extension) Advantage given or gained in any contest; e.g. in football, chess, debate or academic discourse., synonyms: [], antonyms: []}, {definition: The plain surface upon which the figures of an artistic composition are set., synonyms: [], antonyms: [], example: crimson flowers on a white ground}, {definition: In sculpture, a flat surface upon which figures are raised in relief., synonyms: [], antonyms: []}, {definition: In point lace, the net of small meshes upon which the embroidered pattern is applied., synonyms: [], antonyms: [], example: Brussels ground}, {definition: In etching, a gummy substance spread over the surface of a metal to be etched, to prevent the acid from eating except where an opening is made by the needle., synonyms: [], antonyms: []}, {definition: (chiefly in the plural) One of the pieces of wood, flush with the plastering, to which mouldings etc. are attached., synonyms: [], antonyms: [], example: Grounds are usually put up first and the plastering floated flush with them.}, {definition: A soccer stadium., synonyms: [], antonyms: [], example: Manchester United's ground is known as Old Trafford.}, {definition: An electrical conductor connected to the earth, or a large conductor whose electrical potential is taken as zero (such as a steel chassis)., synonyms: [], antonyms: []}, {definition: The area of grass on which a match is played (a cricket field); the entire arena in which it is played; the part of the field behind a batsman's popping crease where he can not be run out (hence to make one's ground)., synonyms: [], antonyms: []}, {definition: A composition in which the bass, consisting of a few bars of independent notes, is continually repeated to a varying melody., synonyms: [], antonyms: []}, {definition: The tune on which descants are raised; the plain song., synonyms: [], antonyms: []}, {definition: The pit of a theatre., synonyms: [], antonyms: []}], synonyms: [earth], antonyms: []}, {partOfSpeech: verb, definitions: [{definition: To connect (an electrical conductor or device) to a ground., synonyms: [earth], antonyms: []}, {definition: To punish, especially a child or teenager, by forcing him/her to stay at home and/or give up certain privileges., synonyms: [gate], antonyms: [], example: Eric, you are grounded until further notice for lying to us about where you were last night!}, {definition: To forbid (an aircraft or pilot) to fly., synonyms: [], antonyms: [], example: Because of the bad weather, all flights were grounded.}, {definition: To give a basic education in a particular subject; to instruct in elements or first principles., synonyms: [], antonyms: [], example: Jim was grounded in maths.}, {definition: To hit a ground ball. Compare fly (verb(regular)) and line (verb)., synonyms: [], antonyms: []}, {definition: To place something on the ground., synonyms: [], antonyms: []}, {definition: To run aground; to strike the bottom and remain fixed., synonyms: [], antonyms: [], example: The ship grounded on the bar.}, {definition: To found; to fix or set, as on a foundation, reason, or principle; to furnish a ground for; to fix firmly., synonyms: [], antonyms: []}, {definition: To cover with a ground, as a copper plate for etching, or as paper or other materials with a uniform tint as a preparation for ornament., synonyms: [], antonyms: []}, {definition: To improve or focus the mental or emotional state of., synonyms: [], antonyms: [], example: I ground myself with meditation.}], synonyms: [earth, gate], antonyms: []}] meanings found:PartOfSpeech: 'noun' Meaning: '{definition: The surface of the Earth, as opposed to the sky or water or underground., synonyms: [], antonyms: [], example: Look, I found a ten dollar bill on the ground!}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: Terrain., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: Soil, earth., synonyms: [], antonyms: [], example: The fox escaped from the hounds by going to ground.}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The bottom of a body of water., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: Basis, foundation, groundwork, legwork., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: (chiefly in the plural) Reason, (epistemic) justification, cause., synonyms: [], antonyms: [], example: He could not come on grounds of health, or on health grounds.}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: Background, context, framework, surroundings., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The area on which a battle is fought, particularly as referring to the area occupied by one side or the other. Often, according to the eventualities, "to give ground" or "to gain ground"., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: (by extension) Advantage given or gained in any contest; e.g. in football, chess, debate or academic discourse., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The plain surface upon which the figures of an artistic composition are set., synonyms: [], antonyms: [], example: crimson flowers on a white ground}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: In sculpture, a flat surface upon which figures are raised in relief., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: In point lace, the net of small meshes upon which the embroidered pattern is applied., synonyms: [], antonyms: [], example: Brussels ground}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: In etching, a gummy substance spread over the surface of a metal to be etched, to prevent the acid from eating except where an opening is made by the needle., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: (chiefly in the plural) One of the pieces of wood, flush with the plastering, to which mouldings etc. are attached., synonyms: [], antonyms: [], example: Grounds are usually put up first and the plastering floated flush with them.}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: A soccer stadium., synonyms: [], antonyms: [], example: Manchester United's ground is known as Old Trafford.}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: An electrical conductor connected to the earth, or a large conductor whose electrical potential is taken as zero (such as a steel chassis)., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The area of grass on which a match is played (a cricket field); the entire arena in which it is played; the part of the field behind a batsman's popping crease where he can not be run out (hence to make one's ground)., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: A composition in which the bass, consisting of a few bars of independent notes, is continually repeated to a varying melody., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The tune on which descants are raised; the plain song., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'noun' Meaning: '{definition: The pit of a theatre., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To connect (an electrical conductor or device) to a ground., synonyms: [earth], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To punish, especially a child or teenager, by forcing him/her to stay at home and/or give up certain privileges., synonyms: [gate], antonyms: [], example: Eric, you are grounded until further notice for lying to us about where you were last night!}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To forbid (an aircraft or pilot) to fly., synonyms: [], antonyms: [], example: Because of the bad weather, all flights were grounded.}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To give a basic education in a particular subject; to instruct in elements or first principles., synonyms: [], antonyms: [], example: Jim was grounded in maths.}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To hit a ground ball. Compare fly (verb(regular)) and line (verb)., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To place something on the ground., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To run aground; to strike the bottom and remain fixed., synonyms: [], antonyms: [], example: The ship grounded on the bar.}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To found; to fix or set, as on a foundation, reason, or principle; to furnish a ground for; to fix firmly., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To cover with a ground, as a copper plate for etching, or as paper or other materials with a uniform tint as a preparation for ornament., synonyms: [], antonyms: []}['definition']'
PartOfSpeech: 'verb' Meaning: '{definition: To improve or focus the mental or emotional state of., synonyms: [], antonyms: [], example: I ground myself with meditation.}['definition']'


Solution 2: PaMcD

I ended up using a factory style initalization.

I had tried this previously with the keyword factory and got an error saying it cant be async, but if i just used the static keyword instead its fine. Apparently it doesnt make a difference.

    // import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'dart:convert';
import 'dart:developer' as devtools show log;

// main() async {
//   print('start');
//   WordDefintion wordDefinition = await WordDefintion.create("ground");

//   print(wordDefinition.toString());
// }

class WordDefintion {
  late String word;
  List<dynamic>? meanings;
  int? meaningsCount;
  List<dynamic>? definitions;
  // bool hasDefinition;

  WordDefintion._create();

  /// Public factory
  static Future<WordDefintion> create(word) async {
    // Call the private constructor
    var component = WordDefintion._create();

    // Do initialization that requires async
    await component.fromFreeDictionary(word);

    // Return the fully initialized object
    return component;
  }

  static String freeDictionaryUrl = 'api.dictionaryapi.dev';

  Future<void> fromFreeDictionary(inputWord) async {
    Future<List<dynamic>> retrieveFreeDefinition(inputWord) async {
      final client = RetryClient(http.Client());
      try {
        var response = await client.read(
            Uri.https(freeDictionaryUrl, '/api/v2/entries/en/$inputWord'));
        return jsonDecode(response);
      } finally {
        client.close();
      }
    }

    try {
      print("Try");
      var responseJson = await retrieveFreeDefinition(inputWord);
      var localdefinitions = [];
      word = inputWord;
      meanings = responseJson[0]['meanings'];
      meaningsCount = responseJson[0]['meanings'].length;

      for (var meaning in meanings!) {
        var partOfSpeech = meaning['partOfSpeech'];
        for (var definition in meaning['definitions']) {
          var singleDefinition = {
            "partOfSpeech": partOfSpeech,
            "definition": definition['definition']
          };
          localdefinitions.add(singleDefinition);
        }
      }

      definitions = localdefinitions;
    } catch (e) {
      meanings = null;
      meaningsCount = null;
    }
  }

  @override
  String toString() {
    String outString = 'Word: $word\n';

    if (definitions != null) {
      outString += "Meanings Count: $meaningsCount\n";
      outString += "Definitions Count: ${definitions!.length}\n";

      for (var definition in definitions!) {
        outString += definition.toString();
      }
    } else {
      outString += "No definition available";
    }

    return outString;

  }
}