Bad state: Cannot set the body fields of a Request with content-type "application/json"
HttpDartFlutterHttp Problem Overview
Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};
var response = await post(Urls.getToken,
headers: headers,
body: {"grant_type":"password","username":"******","password":"*****","scope":"offline_access"},
);
When I execute this I am unable to recieve data and the error thrown is
Bad state: Cannot set the body fields of a Request with content-type "application/json"
Http Solutions
Solution 1 - Http
You need to wrap the body in jsonEncode
.
import 'package:http/http.dart' as http;
import 'dart:convert';
Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};
final msg = jsonEncode({"grant_type":"password","username":"******","password":"*****","scope":"offline_access"});
var response = await post(Urls.getToken,
headers: headers,
body: msg,
);
Solution 2 - Http
Use jsonEncode
to wrap your body object
.
import 'package:http/http.dart' as http;
import 'dart:convert';
var headers = {
'Content-Type':'application/json',
'authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='
};
final body = {
'username':'foo',
'password':'pass123'
}
var response = await post(
Urls.getToken,
headers: headers,
body: jsonEncode(body), // use jsonEncode()
);
Why jsonEncode
?
body: It can be a HTML, JSON or XML, etc. This mean is we need to send/recive data in that perticular format. You can set this in content-type
header its default value is text/plain
.
As you set the content-type
header to JSON
you must have to pass a "valid" JSON as the body. But you are passing Map<String, String>
as the body, which obviously throws an error.
So to solve this issue you need to change (or encode
) your Map<String, String>
data to JSON
data.
Best way to do this is to use jsonEncode
function.
Solution 3 - Http
had similar issue with http library...changed for dio 2.1.0 and the problem with headers is gone.
jsonEncode(body) didn't do the trick, because the docs say:
> Sends an HTTP POST request with the given headers and body to the given URL, which can be a [Uri] or a [String].
> [body] sets the body of the request. It can be a [String], a [List
> If [body] is a List, it's used as a list of bytes for the body of the request.
> If [body] is a Map, it's encoded as form fields using [encoding]. The
content-type of the request will be set to
"application/x-www-form-urlencoded"
; this cannot be overridden.
[encoding] defaults to [utf8].
> For more fine-grained control over the request, use [send] instead.
Future<Response> post(url, {Map<String, String> headers, body, Encoding encoding});
Solution 4 - Http
Map<String,String> header = {'Content-Type':'application/json-patch+json','accept':'application/json'};
final msg = jsonEncode({"username":"$emailorPhoneN","password":"$passwrod"});
try {
var response = await http.post(UrlConstants.loginUrl, headers: header, body: msg,
).timeout(Duration(seconds: httpDuration));
var convert = json.decode(response.body);
print('**********Data from server $convert');
if (convert == null) {
return null;
} else {
String token = convert['token'];
if (token != null) {
SignUpModel signUpModel = SignUpModel.fromJson(convert);
return signUpModel;
} else {
//*** GET Error message from the API provider.....
SignUpModel signUpModel = SignUpModel.fromJson(convert);
return signUpModel;
}
}
Solution 5 - Http
the exception is caused by incorrectly setting bodyFields. See: bodyFields
bodyFields is for form-encoded data, not JSON. For an example of how to POST JSON see: Write HTTP servers
So you're trying to pass a Map as the body. In this case it would assume that you are actually doing a application/x-www-form-urlencoded
. What you need to do is encode the Map
as a string and then do what you're doing.
Example
Future<http.Response> patchAPICall(
String url, Map param, String token) async {
var responseJson;
try {
final response = await http.patch(Uri.parse(url),
body: jsonEncode(param),
headers: {
"Authorization": token,
"Content-Type": "application/json"
}).timeout(const Duration(seconds: 60),
onTimeout: () => throw TimeoutException(
'The connection has timed out, Please try again!'));
responseJson = response;
} on SocketException {
throw FetchDataException("You are not connected to internet");
} on TimeoutException {
print('Time out');
throw TimeoutException("The connection has timed out, Please try again");
}
return responseJson;
}
Solution 6 - Http
For me, jsonencode(body)
did not work.
This is worked for me instead:
body = json.encode(body);
http.post(Uri.parse(uri), headers: header, body: body);