Why put flutter returning bad request? - flutter

I am making a mobile app using Flutter & Dart. I have a put request that updated a database. The request keeps giving a bad request 400. The code is as follow:
Future<void> updateStudent(int id, Student newStudent) async {
var res = await http.put(
Uri.parse('https://10.0.2.2:7030/api/Student/{id}?Id=7'),
headers: {
"Accept": "application/json",
"content-type": "application/json"
},
body: json.encode({
'id': newStudent.id,
'dep_id': newStudent.depId,
'name_ar': newStudent.nameAr,
'name_en': newStudent.nameEn,
'name_moth': newStudent.nameMoth,
'birth': newStudent.birth,
}));
}
I tried many suggestions. Also I tried to do the request this way code. But same issue.
The API is working just fine with postman but for some reason it does not with Flutter. I postman I used query params and body with raw json There is something wrong but I am not able to find it.
Any idea or suggestions?
Update
I debugged the request and it showing an error on "BodyField" stating the Bad state: Cannot access body fields of a Request without "content-type : application/x-www-form-urlencoded
Even though I am using json.
I also tried to change the content type but it is giving unsupported media type.
in postman I am using put method with this url
https://localhost:7030/api/Student/{id}?Id=7

Change your url and body to this:
var url = Uri.https('https://10.0.2.2:7030', 'api/Student/{id}');
var res = await http.put(
url,
headers: {
"Accept": "application/json",
"content-type": "application/json"
},
body: {
'id': newStudent.id,
'dep_id': newStudent.depId,
'name_ar': newStudent.nameAr,
'name_en': newStudent.nameEn,
'name_moth': newStudent.nameMoth,
'birth': newStudent.birth,
});
you already add id in body, no need to put it in url too.

Related

Dart TypeError : type 'JSString' is not a subtype of type 'int' for a Http POST request

I'm building an application using flutter where the user provides a string and a set of values must be returned.
I'm unable to figure out what is the cause for the issue.I tried all the solutions provided to the questions similar to this issue but weren't successful.Any help would be really appreciated.
I converted the actual code to dart only, for easy testing online using dartpad.
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;
final body = <String, String>{
"id": '1',
"language": "en",
"text": "I love this service",
};
final headers = <String, String>{
"content-type": "application/json",
"X-RapidAPI-Key": "7f980b3d2cmsh1d666b571febd6ep11df80jsna27f76c06e6b",
"X-RapidAPI-Host": "big-five-personality-insights.p.rapidapi.com",
};
void main(List<String> arguments) async {
final response = await http.post(
Uri.parse('https://big-five-personality-insights.p.rapidapi.com/api/big5'),
headers: headers,
body: [
convert.jsonEncode(body),
],
);
if (response.statusCode == 201) {
// If the server did return a 201 CREATED response,
// then parse the JSON.
print('success');
print(convert.jsonDecode(response.body));
} else {
// If the server did not return a 201 CREATED response,
// then throw an exception.
print('fail');
throw Exception('Failed to get a response.');
}
}
You have a bad value for the body argument of http.post.
The documentation for the method states:
body sets the body of the request. It can be a String, a List or a Map<String, String>. [...] If body is a List, it's used as a list of bytes for the body of the request.
Since the API you are talking to requires an array to be sent, you want to wrap the body in a list before converting it all to json (note how the brackets have shifted inside the convert method:
final response = await http.post(
Uri.parse('https://big-five-personality-insights.p.rapidapi.com/api/big5'),
headers: headers,
body: convert.jsonEncode([body]),
);
Sidenote: The API responds with statusCode 200 on a successful request, not 201; at least in my testing.
The body parameter of a post method sets the body of the request. It can be a String, a List or a Map<String, String>. If it's a String, it's encoded using encoding and used as the body of the request. The content-type of the request will default to "text/plain".
As you passed it as a List, then it expects it to be a List of integers, but you are passing it a List type (or in this specific case List type). Here is a fixed code.
final response = await http.post(
Uri.parse('https://big-five-personality-insights.p.rapidapi.com/api/big5'),
headers: headers,
body: convert.jsonEncode(body),
);

Is there any way to convert the response body to XML in flutter?

I have a get request in flutter, the response body comes as json, is there any way to have it in XML?
In the Swagger UI it comes as XML but I don't know why it comes as Json in my request.
I am using this lines:
final response = await http.get(Uri.parse(selectedURL));
print(response.body);
You probably need to set the Accept header to something like:
Accept: application/xml
Something like this might do the trick:
final response = await http.get(
Uri.parse(selectedURL),
headers: {
'Accept': 'application/xml',
},
);
print(response.body);

http.post problem after Flutter 2 upgrade

I have just updated to Flutter 2. I updated all the dependencies including http. Now I have a problem with the following:
Future<UserLogin> fetchStaff(String pUserName, String pPassword) async {
final response = await http
.post(Uri.encodeFull('$kBaseUrl/LoginService/CheckLogin'),
headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
body: '{ "pUser": "$pUserName", "pPassword": "$pPassword"}')
.timeout(Duration(seconds: kTimeOutDuration));
I'm getting an error on the: Uri.encodeFull('$kBaseUrl/LoginService/CheckLogin'
"The argument type 'String' can't be assigned to the parameter type 'Uri'."
$kBaseUrl = 'https://subdom.mydomain.com:443/mobile';
What do I need to change?
Post method used to take string previously, now they have modified to Uri
so used, Uri.parse to get the uri
.post(Uri.parse(Uri.encodeFull('$kBaseUrl/LoginService/CheckLogin'))
Like the error says, this is because post function expects a Uri and you have passed a String (returned by Uri.encodeFull) to it. You need to use Uri.parse to pass a Uri to it.
final response = await http
.post(Uri.parse('$kBaseUrl/LoginService/CheckLogin'),
If you had a String, such as:
String strUri="${yourBaseUrl}/yourPath/yourFile";
Using
http.post(Uri.parse(strUri),
headers: {...},
body: {...},
);
is enough to get all working back.
You may try Uri.tryParse(strUri) to handle null if the uri string is not valid as a URI or URI reference.

Converting my Postman Call to Dart/Flutter API Call

I hope to use nutritionix api to get food information for the users of my application, I manage to get the call to work in Postman, however I cannot convert it to dart code. I am getting this error: '{message: Unexpected token " in JSON at position 0}'
Here is my (POST) postman call:
Here is my attempt at converting that to dart code:
Future<void> fetchNutritionix() async {
String url = 'https://trackapi.nutritionix.com/v2/natural/nutrients';
Map<String, String> headers = {
"Content-Type": "application/json",
"x-app-id": "5bf----",
"x-app-key": "c3c528f3a0c68-------------",
"x-remote-user-id": "0",
};
String query = 'query: chicken noodle soup';
http.Response response =
await http.post(url, headers: headers, body: query);
int statusCode = response.statusCode;
print('This is the statuscode: $statusCode');
final responseJson = json.decode(response.body);
print(responseJson);
//print('This is the API response: $responseJson');
}
Any help would be appreciated! And, again thank you!
Your postman screenshot shows x-www-form-urlencoded as the content-type, so why are you changing that to application/json in your headers? Remove the content type header (the package will add it for you) and simply pass a map to the body parameter:
var response = await http.post(
url,
headers: headers,
body: {
'query': 'chicken soup',
'brand': 'acme',
},
);
Also you can now generate Dart code (and many other languages) for your Postman request by clicking the Code button just below the Save button.
click the three dotes button in request tab and select code option then select your language that you want convert code to
review the query you're posting
your Postman input is x-www-form-urlencoded instead of plain text
String query = 'query: chicken noodle soup';
why don't you try JSON better
String query = '{ "query" : "chicken noodle soup" }';

http.post is being fired twice

I am a bit new to Flutter, and I am building a screen that posts data to an API built in PHP mon my hosting server. The API is built by me which receives a JSON object and then saves the data.
The app is working fine, and API is receiving the data, but the http.post seems is firing twice ( calling the API twice)
Which makes my API saves the record twice. there is no possible way for me to check before adding the send record. as My API simply saves a new record so whenever it receives a call it simply saves it and returns back a value for the mobile App ( built in Flutter).
If I use a condition to check, this way the first call will return correct data to the mobile app, but the second one will return an error for the mobile app since the record already exists.
I have read about the Access-Control-Allow-Origin and how it might be the issue and put it my my .httaccess file
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
but no luck.
any idea.
Note I am using a shared hosting.
Code I use in Flutter:
class _PostADToServerState extends State<PostADToServer> {
Future<List<JSBResponse>> _postRequest() async {
// print('Call API function is called');
Map<String, dynamic> myAd = {
"isbn10": widget.title.isbn10,
"isbn13": widget.title.isbn13,
... [Some fields]
"titleCondition": widget.title.titleCondition,
"priceIs": widget.title.priceIs,
"school_name": widget.title.schoolName
};
String json = jsonEncode(myAd);
var url = 'https://www.example.com/xapis/save_new_ad.php';
var body = json;
var data = await http.post(url,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: body);
var jsonData = jsonDecode(data.body);
Code in my PHP API starts with the following:
$data = file_get_contents('php://input');
$theTitle = json_decode($data);
Then I use the content I find in the $theTitle object as the following:
$title = $theTitle->title;