search method

Future<List<FmData>> search({
  1. required String q,
  2. bool geoJson = false,
  3. required FmSearchParams p,
})

Search addresses using query

Setting geoJson to true will load heavy data and may slow down the API call. Use it only if detailed geographic data is required.

Implementation

Future<List<FmData>> search({
  required String q,
  bool geoJson = false,
  required FmSearchParams p,
}) async {
  q = q.trim();
  if (q.isEmpty) return [];

  // 1. Form query
  final box = _calculateBoundingBox(p.loc, p.radius);
  final query = {
    'q': q,
    'limit': 10,
    'format': 'jsonv2',
    'polygon_geojson': geoJson ? 1 : 0,
    'accept-language': p.langs.map((e) => e.trim()).join(','),
    if (p.countries != null)
      'countrycodes': p.countries?.map((e) => e.trim()).join(','),
    if (box != null) 'bounded': 1,
    if (box != null) 'viewbox': '${box[0]},${box[1]},${box[2]},${box[3]}',
  };

  // 2. Check local db
  try {
    final data = await _dbService.getSearch(query);
    if (data != null) {
      return data.map((e) => FmData.fromJSON(e)).toList();
    }
  } catch (e, st) {
    _logService.logError(e, st);
  }

  // 3. Wait for new request
  final success = await _waitForNewRequest(RequestType.nominatim);
  if (!success) return [];

  // 4. Make API call
  final url =
      '${_searchURL.url}?${query.keys.map((k) => '$k=${query[k]}').join('&')}';

  final res = await _apiService.request(
    url: url,
    userAgent: _userAgent ?? _systemService.userAgent,
  );

  // 5. Parse response & save it to local db
  try {
    await _dbService.saveSearch(query, res.data);
    return (res.data as List).map((e) => FmData.fromJSON(e)).toList();
  } catch (e, st) {
    _logService.logError(
      e,
      st,
      res: res.toString(),
      req: 'query: $q | params: ${p.toString()}',
    );
    return [];
  }
}