Utilizo dardos y aleteo para aplicaciones móviles. Utilizo mi api para obtener datos del servidor. Pero encontré un problema, tal vez el problema del núcleo del dardo.

Necesito agregar queryParams complejos a mi URL como

Map<String, Map<String, List<String>>>{"a": {"b": ["c","d"]}, "e": {}}

Yo uso Uri.parse(url).replace(queryParams: myQueryParams).toString()

Pero Uri.replace() solo acepta Map<String, Iterable<String>> y arroja un error

Unhandled Exception: type '_InternalLinkedHashMap<String, List<String>>' is not a subtype of type 'Iterable<dynamic>'

Encontré un método que arroja este error.

  static String _makeQuery(String query, int start, int end,
      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters) {
    if (query != null) {
      if (queryParameters != null) {
        throw ArgumentError('Both query and queryParameters specified');
      }
      return _normalizeOrSubstring(query, start, end, _queryCharTable,
          escapeDelimiters: true);
    }
    if (queryParameters == null) return null;

    var result = StringBuffer();
    var separator = "";

    void writeParameter(String key, String value) {
      result.write(separator);
      separator = "&";
      result.write(Uri.encodeQueryComponent(key));
      if (value != null && value.isNotEmpty) {
        result.write("=");
        result.write(Uri.encodeQueryComponent(value));
      }
    }

    queryParameters.forEach((key, value) {
      if (value == null || value is String) {
        writeParameter(key, value);
      } else {
        Iterable values = value;
        for (String value in values) {
          writeParameter(key, value);
        }
      }
    });
    return result.toString();
  }

Entonces, mi pregunta es ¿hay algún método en Dart para agregar mis queryParams a la URL o necesito crearlo por mi cuenta?

0
Theillko OSG 9 oct. 2019 a las 18:43

1 respuesta

La mejor respuesta

He modificado el método original y ahora funciona.

class UrlCreator {
  static String addQueryParams(String url, Map<String, dynamic> queryParams) {
    var result = StringBuffer();
    var separator = "";

    void writeParameter(String key, String value) {
      result.write(separator);
      separator = "&";
      result.write(Uri.encodeQueryComponent(key));
      if (value != null && value.isNotEmpty) {
        result.write("=");
        result.write(Uri.encodeQueryComponent(value));
      }
    }

    void buildQuery(Map queryParams, {parentKey}){
      queryParams.forEach((key, value){
        print("parentKey = $parentKey Key = $key value = $value");
        if (value == null || value is String) {
          var newKey = parentKey != null ? "$parentKey[$key]" : key;
          writeParameter(newKey, value);
        } else if (value is Map) {
          buildQuery(value, parentKey: key);
        } else {
          Iterable values = value;
          var newKey = parentKey != null ? "$parentKey[$key][]" : "$key[]";
          for (String value in values) {
            writeParameter(newKey, value);
          }
        }
      });
    }

    buildQuery(queryParams);

    return url + "?" + result.toString();
  }
}

0
Theillko OSG 10 oct. 2019 a las 07:55