fetchSuggestions method

Future<List<Suggestion>> fetchSuggestions(
  1. String input, {
  2. bool includeFullSuggestionDetails = false,
  3. required List<AutoCompleteType> types,
})

includeFullSuggestionDetails if we should include ALL details that are returned in API suggestions. (This is sent as true when the onInitialSuggestionClick is in use) postalCodeLookup if we should request postal_code type return information instead of address type information.

Implementation

Future<List<Suggestion>> fetchSuggestions(
  String input, {
  bool includeFullSuggestionDetails = false,
  required List<AutoCompleteType> types,
}) async {
  /// OK, we need to check the types array..
  String typesString = '';
  for (final type in types) {
    if (type.onlySingleValueAllowed && types.length > 1) {
      throw Exception(
        'If $type is specified then it is the ONLY autocomplete type allowed by Google Places. See https://developers.google.cn/maps/documentation/places/web-service/autocomplete#types',
      );
    }
    if (typesString.isNotEmpty) typesString += '|';
    typesString += type.typeString;
  }
  if (types.length > 5) {
    throw Exception(
      'A maximum of 5 autocomplete types are allowed by Google Places. See https://developers.google.cn/maps/documentation/places/web-service/autocomplete#types',
    );
  }

  final Map<String, dynamic> parameters = <String, dynamic>{
    'input': input,
    'types': typesString,
    'key': mapsApiKey,
    'sessiontoken': sessionToken,
  };

  if (language != null) {
    parameters.addAll(<String, dynamic>{'language': language});
  }

  if (componentCountries.isNotEmpty) {
    List<String> componentCountriesList = componentCountries.toList();
    String components =
        componentCountriesList.map((code) => 'country:$code').join('|');
    parameters.addAll(<String, dynamic>{'components': components});
  }

  final Uri request = Uri(
    scheme: 'https',
    host: 'maps.googleapis.com',
    path: '/maps/api/place/autocomplete/json',
    queryParameters: parameters,
  );

  final response = await client.get(request);

  if (response.statusCode == 200) {
    final result = json.decode(response.body);
    if (result['status'] == 'OK') {
      if (debugJson) {
        printJson(
          result['predictions'],
          title: 'GOOGLE MAP API RETURN VALUE result["predictions"]',
        );
      }

      // compose suggestions in a list
      return result['predictions'].map<Suggestion>((p) {
        if (includeFullSuggestionDetails) {
          // Package everything useful from API json
          final mainText = p['structured_formatting']?['main_text'];
          final secondaryText = p['structured_formatting']?['secondary_text'];
          final terms = p['terms']
              .map<String>((term) => term['value'] as String)
              .toList();
          final types =
              p['types'].map<String>((atype) => atype as String).toList();

          return Suggestion(
            p['place_id'],
            p['description'],
            mainText: mainText,
            secondaryText: secondaryText,
            terms: terms,
            types: types,
          );
        } else {
          // just use the simple Suggestion parts we need
          return Suggestion(p['place_id'], p['description']);
        }
      }).toList();
    }
    if (result['status'] == 'ZERO_RESULTS') {
      return [];
    }
    throw Exception(result['error_message']);
  } else {
    throw Exception('Failed to fetch suggestion');
  }
}