Reputation: 808
I'm trying to make an post request in flutter with content type as url encoded. When I write body : json.encode(data)
, it encodes to plain text.
If I write body: data
I get the error type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast
This is the data object
var match = {
"homeTeam": {"team": "Team A"},
"awayTeam": {"team": "Team B"}
};
And my request
var response = await post(Uri.parse(url),
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: match,
encoding: Encoding.getByName("utf-8"));
Upvotes: 67
Views: 200532
Reputation: 489
You can use addAll()...
var multipart = await http.MultipartFile.fromPath("userfile", file.path);//userFile must match server
var requestMultipart = http.MultipartRequest("POST", Uri.parse("uri"));
requestMultipart.files.add(multipart);
Map<String, String> data = {
"name_of_image": "testName",
"id_image": "2",//if the
"upload_type": "Insert",
"id_location": "2"
};
requestMultipart.fields.addAll(data);
Upvotes: 0
Reputation: 37
If you are using dio you can do it using :
dio.post(
'/info',
data: {'id': 5},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
check https://github.com/flutterchina/dio for more details
Upvotes: 1
Reputation: 511846
I came here just trying to make an HTTP POST request. Here is an example of how to do that:
import 'dart:convert';
import 'package:http/http.dart';
makePostRequest() async {
final uri = Uri.parse('http://httpbin.org/post');
final headers = {'Content-Type': 'application/json'};
Map<String, dynamic> body = {'id': 21, 'name': 'bob'};
String jsonBody = json.encode(body);
final encoding = Encoding.getByName('utf-8');
Response response = await post(
uri,
headers: headers,
body: jsonBody,
encoding: encoding,
);
int statusCode = response.statusCode;
String responseBody = response.body;
}
See also
Upvotes: 28
Reputation: 914
Post encoded URL request
static Future<http.Response> genearalRequest() async {
Map<String,String> headers = new Map();
headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
var data = {
"data1": "datat1 value",
"data2": "value2"
};
var parts = [];
data.forEach((key, value) {
parts.add('${Uri.encodeQueryComponent(key)}='
'${Uri.encodeQueryComponent(value)}');
});
var formData = parts.join('&');
print(formData);
return await http.post('$baseUrl/oauth/token', headers: headers, body: formData);
}
Upvotes: 1
Reputation: 51692
You need to add three additional steps: First, you need to convert the JSON map to a String (using json.encode) Then you need to Uri encode it if you want to send it as application/x-www-form-urlencoded. Lastly, you need to give the parameter that you are posting a name.
For example (note, this is using the dart:io HttpClient, but it's basically the same):
Future<HttpClientResponse> foo() async {
Map<String, dynamic> jsonMap = {
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
};
String jsonString = json.encode(jsonMap); // encode map to json
String paramName = 'param'; // give the post param a name
String formBody = paramName + '=' + Uri.encodeQueryComponent(jsonString);
List<int> bodyBytes = utf8.encode(formBody); // utf8 encode
HttpClientRequest request =
await _httpClient.post(_host, _port, '/a/b/c');
// it's polite to send the body length to the server
request.headers.set('Content-Length', bodyBytes.length.toString());
// todo add other headers here
request.add(bodyBytes);
return await request.close();
}
The above is for the dart:io
version (which, of course, you can use in Flutter)
If you would like to stick with the package:http
version, then you need to tweak your Map a bit. body
must be a Map<String, String>
. You need to decide what you want as your POST parameters. Do you want two: homeTeam and awayTeam? or one, say, teamJson?
This code
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'homeTeam': json.encode(
{'team': 'Team A'},
),
'awayTeam': json.encode(
{'team': 'Team B'},
),
};
Response r = await post(
url,
body: body,
);
produces this on the wire
name=doodle&color=blue&homeTeam=%7B%22team%22%3A%22Team+A%22%7D&awayTeam=%7B%22team%22%3A%22Team+B%22%7D
alternatively, this
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': json.encode({
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
}),
};
Response r = await post(
url,
body: body,
);
produces this on the wire
name=doodle&color=blue&teamJson=%7B%22homeTeam%22%3A%7B%22team%22%3A%22Team+A%22%7D%2C%22awayTeam%22%3A%7B%22team%22%3A%22Team+B%22%7D%7D
the package:http
client takes care of: encoding the Uri.encodeQueryComponent, utf8 encoding (note that that's the default, so no need to specify it) and sending the length in the Content-Length header. You must still do the json encoding.
Upvotes: 61
Reputation: 1152
On the place of "UserModel" write the name of your model and do not pass String in the body it will create a problem using "Map" as given below.
static Future<UserModel> performUserLogin(String username, String password) async{
try{
Map<String, String> headers = {"Content-type": "application/json"};
Map<String, String> JsonBody = {
'username': username,
'password': password
};
print("The JSON Object is here $body");
// make POST request
final response = await http.post(loginAPIURL,body: JsonBody);
// check the status code for the result
int statusCode = response.statusCode;
print("Login calling $response");
if (statusCode == 200){
}else{
return null;
//return UserModel();
throw Exception("Error in login");
}
} catch (e) {
throw Exception(e);
}
}
Upvotes: 1
Reputation: 620
Map<String, String> body = {
'getDetails': 'true'
};
final response = await
http.post("https://example.com/", body: body);
if (response.statusCode == 200) {
//Your code
}
Upvotes: 0
Reputation: 4418
I suggest using the Dio library. It supports a lot with working with APIs.
With newest Dio version. Simply do the following:
BaseOptions options = new BaseOptions(
baseUrl: "https://www.xx.com/api",
connectTimeout: 5000,
receiveTimeout: 3000,);
Dio dio = new Dio(options);
//
Map<String, String> params = Map();
params['username'] = '6388';
params['password'] = '123456';
//
response = await dio.post("/login", data: FormData.fromMap(params));
Upvotes: 3
Reputation: 389
I did it like this with dart's http package. It's not too fancy. My endpoint wasn't accepting the parameters with other methods, but it accepted them like this, with the brackets included in the parameter.
import 'package:http/http.dart' as http;
String url = "<URL>";
Map<String, String> match = {
"homeTeam[team]": "Team A",
"awayTeam[team]": "Team B",
};
Map<String, String> headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
http.post(url, body: body, headers: headers).then((response){
print(response.toString());
});
Upvotes: 0
Reputation: 141
you need to use json.encode
example;
var match = {
"homeTeam": {"team": "Team A"},
"awayTeam": {"team": "Team B"}
};
var response = await post(Uri.parse(url),
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: json.encode(match),
encoding: Encoding.getByName("utf-8"));
Upvotes: 14
Reputation: 1257
I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
dio is very easy to use, in your case you can:
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': {
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
},
};
dio.post("/info",data:body, options:
new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")))
dio can encode the data automatically.
More details please refer to dio.
Upvotes: 31