Reputation: 3425
How do you correctly add query parameters to a Dart http get request? I been unable to get my request to respond correctly when trying to append the '?param1=one¶m2=two' to my url, yet it works correctly in Postman. Here's the gist of my code:
final String url = "https://www.myurl.com/api/v1/test/";
String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one¶m2=two";
Map<String, String> qParams = {
'param1': 'one',
'param2': 'two',
};
var res = await http
.get(Uri.encodeFull("$url${widget.pk}/"),
headers: {HttpHeaders.authorizationHeader: "Token $token",
HttpHeaders.contentTypeHeader: "application/json"},
);
The ${widget.pk} is simply a integer value being pass (See the value 123 in the workingStringInPostman variable.
The qParams is there for connivence, in case a Uri parameter is needed.
A code example would be welcomed.
Upvotes: 129
Views: 182070
Reputation: 10925
You'll want to construct a Uri
and use that for the request. Something like
final queryParameters = {
'param1': 'one',
'param2': 'two',
};
final uri =
Uri.https('www.myurl.com', '/api/v1/test', queryParameters);
final response = await http.get(uri, headers: {
HttpHeaders.authorizationHeader: 'Token $token',
HttpHeaders.contentTypeHeader: 'application/json',
});
See https://api.dartlang.org/stable/2.0.0/dart-core/Uri/Uri.https.html
Upvotes: 220
Reputation: 683
This is worked for me.
_init() async {
DateTime endDate = DateTime.now();
DateTime startDate = endDate.subtract(Duration(days: 30 * 11));
var response = await Api.get(
"mover/dashboard/column-chart?start=$startDate&end=$endDate");
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
if (mounted) {
setState(() {});
}
}
}
Api.dart
static Future<http.Response> get(path) async {
String? token = await Store.read('token');
try {
var response = await http.get(
Uri.parse('$basePath/api/moving/$path'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json'
},
);
return response;
} catch (err) {
return http.Response('${err.toString()}', 400);
}
}
Upvotes: -1
Reputation: 71
final uri = Uri.parse("${ApiConstants.baseUrl}/blog/post/blog-post-list");
uri.replace(queryParameters: {"location": location});
final Response response = await _apiRepository.getApi(uri);
if (response.statusCode == 200 || response.statusCode == 201) {
final content = await jsonDecode(response.body);
final data = await content["data"] as List;
List<PostModel> list = [];
for (var i in data) {
final postModel = PostModel.fromJson(i);
list.add(postModel);
}
this works as of today
Upvotes: 0
Reputation: 629
this is more simple
final uri = Uri.parse('$baseUrl/v1/endpoint').replace(queryParameters: {
'page': page,
'itemsPerPage': itemsPerPage,
});
final response = await client.get(uri);
Upvotes: 58
Reputation: 2297
U can use this:
String _getParamsFromBody( Map<String, dynamic>? body) {
String params = '?';
for (var i = 0; i < body!.keys.length; i++) {
params += '${List.from(body!.keys)[i]}=${List.from(body!.values)[i]}';
if (i != body!.keys.length - 1) {
params += '&';
}
}
log(params);
return params;
}
Uri.parse("https://www.myurl.com/api/v1/test"+ _getParamsFromBody({'param1':'value1','param2':'value2}))
Upvotes: 0
Reputation: 49
The following function copied from flutter code can be used to create the query string part only:
String queryString(Map<String, dynamic> queryParameters) {
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();
}
Usage:
var q = queryString({"a":"b&", "c":["1","xyz"]});
// a=b%26&c=1&c=xyz
Upvotes: 1
Reputation: 1196
If you dont want to override the scheme of base endpoint url, use the below technique to convert the map to query string and append it to the base endpoint url
var endpointUrl = 'https://www.myurl.com/api/v1/user';
Map<String, String> queryParams = {
'param1': '1',
'param2': '2'
};
var headers = {
HttpHeaders.authorizationHeader: 'Token $token',
HttpHeaders.contentTypeHeader: 'application/json',
}
String queryString = Uri.parse(queryParameters: queryParams).query;
var requestUrl = endpointUrl + '?' + queryString; // result - https://www.myurl.com/api/v1/user?param1=1¶m2=2
var response = await http.get(requestUrl, headers: headers);
Upvotes: 38
Reputation: 3801
Use Uri
to pass query parameters like.
final String url = "https://www.myurl.com/api/v1/test/${widget.pk}/";
Map<String, String> qParams = {
'param1': 'one',
'param2': 'two',
};
Map<String, String> header = {
HttpHeaders.authorizationHeader: "Token $token",
HttpHeaders.contentTypeHeader: "application/json"
};
Uri uri = Uri.parse(url);
final finalUri = uri.replace(queryParameters: qParams); //USE THIS
final response = await http.get(
finalUri,
headers: header,
);
Upvotes: 7
Reputation: 381
I made a little util function which resolves the authority
/ unencodedPath
parameters for Uri
creation.
Uri createUri(String url, [Map<String, String> queryParameters]) {
var isHttp = false;
if (url.startsWith('https://') || (isHttp = url.startsWith('http://'))) {
var authority = url.substring((isHttp ? 'http://' : 'https://').length);
String path;
final index = authority.indexOf('/');
if (-1 == index) {
path = '';
} else {
path = authority.substring(index);
authority = authority.substring(0, authority.length - path.length);
}
if (isHttp) {
return Uri.http(authority, path, queryParameters);
} else {
return Uri.https(authority, path, queryParameters);
}
} else if (url.startsWith('localhost')) {
return createUri('http://' + url, queryParameters);
}
throw Exception('Unsupported scheme');
}
Here is the example code which uses it:
final String url = 'https://www.myurl.com/api/v1/test/${widget.pk}';
Map<String, String> qParams = {
'param1': 'one',
'param2': 'two',
};
var res = await http.get(
createUri(url, qParams),
headers: {
HttpHeaders.authorizationHeader: "Token $token",
HttpHeaders.contentTypeHeader: "application/json"
},
);
Upvotes: 0
Reputation: 267584
Use Uri
constructor to build your query, it has a queryParameter
property.
var uri = Uri(
scheme: 'https',
host: 'example.com',
path: '/foo/bar',
fragment: 'baz',
queryParameters: _yourQueryParameters,
);
var response = await http.get(uri);
if (response.statusCode == 200) {
var json = jsonDecode(response.body);
// Do whatever you want to do with json.
}
Upvotes: 6
Reputation: 205
Got the same question. The accepted answer won't work if my url is localhost with port like https://localhost:5001
. After spending 1 day to search for solution, I come up with Dio library. Following is my solution using Dio
:
var _dio = new Dio();
var options = new Options;
options.headers['Authorization'] = 'bearer $token';
options.contentType = 'application/json';
String url = "https://www.myurl.com";
Map<String, String> qParams = {
'param1': 'one',
'param2': 'two',
};
var res = await _dio.get(url, options: options, queryParameters: qParams);
Hope this helps.
Upvotes: 8
Reputation: 85
The accepted answer didn't work for me but adding a '&' without quotes to end of the URL solves my problem. In this case, change the following line:
String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one¶m2=two";
to this: (Notice the '&' at the end).
String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one¶m2=two&";
Upvotes: 4
Reputation: 1893
There is a dart package that provides some helper classes for http requests.
BasicUtils : https://github.com/Ephenodrom/Dart-Basic-Utils
Install it with:
dependencies:
basic_utils: ^1.4.0
Usage
You can add a map of headers and query parameters to each request. See the example :
// Define some headers and query parameters
Map<String, String> headers = {
"Accept": "application/json"
};
Map<String, String> queryParameters = {
"foo": "bar"
};
// Body
String body = "{ 'some':'json'}";
// Send request
Map<String, dynamic> responseData = await HttpUtils.postForJson("api.com/dosomething", body,
headers: headers, queryParameters: queryParameters);
Additional information :
These are all methods from the HttpUtils class.
Future<Map<Response> getForFullResponse(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> getForJson(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<String> getForString(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<Response> postForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> postForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> postForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response> putForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> putForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> putForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response deleteForFullResponse(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> deleteForJson(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> deleteForString(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Map<String, dynamic> getQueryParameterFromUrl(String url);
String addQueryParameterToUrl(String url, Map<String, dynamic> queryParameters);
Upvotes: 2