Dart: convert map into query string

Viewed 8961

I have a situation where I need to turn a Map into a query String (after the first ?). For instance if I have the following map:

Map json = {
    "email":  eml,
    "password": passwd
};

And a base URL:

String baseURL = "http://localhost:8080/myapp";

Then I need something that converts the json Map into the query string of the base URL:

String fullURL = parameterizeURL(baseURL, json);

// Prints: http://localhost:8080/myapp?email=blah&password=meh
// (if "blah" was entered as the email, and "meh" was entered as the password)
print(fullURL);

I found this query String-to-map library on Git, but I need the inverse of this! It would be great to get URL encoding in there as well.

I'm happy to make something homegrown but being so new to Dart I was wondering if there's anything on pub/Github/the etherspehere that does this already.

9 Answers

TL;DR

String queryString = Uri(queryParameters: {'x': '1', 'y': '2'}).query;

print(queryString); // x=1&y=2
final yourMap = {'x': '1', 'y': '2'};
final queryString = yourMap.toMap().entries.map((e) => '${e.key}=${e.value}').join('&');
print(queryString); // x=1&y=2

i wrote a recursive function to turn any Map<String, dynamic> to query String.

String getQueryString(Map params, {String prefix: '&', bool inRecursion: false}) {

    String query = '';

    params.forEach((key, value) {

        if (inRecursion) {
            key = '[$key]';
        }

        if (value is String || value is int || value is double || value is bool) {
            query += '$prefix$key=$value';
        } else if (value is List || value is Map) {
            if (value is List) value = value.asMap();
            value.forEach((k, v) {
                query += getQueryString({k: v}, prefix: '$prefix$key', inRecursion: true);
            });
        }
   });

   return query;
}

example:

Map<String, dynamic> params = {'aa': 1.1, 'bb': [2, [3, ['5', {'66': 777}]]]};
String query = getQueryString(params);
print(query);

this code will print:

&aa=1.1&bb[0]=2&bb[1][0]=3&bb[1][1][0]=5&bb[1][1][1][66]=777

I faced the same problem and wrote this function for me. Here it is in case someone needs it:

String makeQuery(Map<String, dynamic>? data) {
  var result = [];

  if (data != null) {
    data.forEach((key, value) {
      if (value != null && (value is! String || value.trim().isNotEmpty)) {
        result.add('$key=${value.toString()}');
      }
    });
  }

  return result.join('&');
}

I think that the easiest way to to generate a query string from a Map is to use Uri.replace. It's basically the same thing as using the Uri constructor, but it avoids needing to manually copy all of the other parts of the URL:

String baseURL = "http://localhost:8080/myapp";

Map json = {
  "email":  eml,
  "password": passwd
};

String fullURL = Uri.parse(baseURL).replace(queryParameters: json).toString();

I realize that I'm responding to an old question, but I feel compelled to additionally point out that you probably shouldn't be sending passwords via query strings.

This is my own function that will escape the parameters that have null value

String generateQueryString(Map<String, dynamic> params) {
    List queryString = [];
    params.forEach((key, value) {
      if (value != null) {
        queryString.add(key + '=' + value.toString());
      }
    });
    return queryString.join('&');
  }

  String query = generateQueryString({
    'CategoryId': '1',
    'MinAmount': 0,
    'MaxAmount': 2012,
    'Quantity': 1,
  });

  print(query); // CategoryId=1&MinAmount=0&MaxAmount=2012&Quantity=1
Related