How do I solve this [DioErrorType.response]: Http status error [422] - flutter

I am trying to send a form data to a server and it is returning this error back : Error Message: DioError [DioErrorType.response]: Http status error [422]
How do I solve this issue?
Map<String, String> sentData = {
'firstname': data['first_name'].trim(),
'lastname': data['last_name'].trim(),
'email': data['email'].trim(),
'phone': data['phone'].trim(),
'password': data['password'],
'password_confirmation': data['password_confirmation'],
'country_id': id.toString(),
};
debugPrint('AuthControllerData : Data to Send to Server = $sentData');
final formData = dio.FormData.fromMap(sentData);
var response = await client.HttpClient(resource: 'auth/register').post(data: formData);
debugPrint('AuthController response: $response');
Is this the right way to send the FormData and are there better way like the options I have to set while using the Dio package to send formdata?

Related

Getting FormatException response from my flutter api response

I have a button which when clicked, prints out response.
This is how the response is
{
"status": "success",
"user": "Worked well"
}
when I test it with postman it works fine, but when I try it from my flutter project, I get this error
I/flutter ( 5147): Response: - Instance of 'Response'
I/flutter ( 5147): FormatException: Unexpected character (at character 1)
I/flutter ( 5147): <!DOCTYPE html>
I/flutter ( 5147): ^
This is my flutter code:
http.Response response = await http.post(
Uri.parse(url + 'testMe.php'),
headers: headers,
body: body,
);
print('response ${response}');
if (response.body.isNotEmpty) {
json.decode(json.encode(response.body));
} else {
print('Response is empty...');
}
One thing I noticed is that, sometimes it does not throw the error above in flutter, it works fine and sometimes it throws the error, so I don't why it happen that way.
Flu
Postman Header
This worked for me:
Map<String, String> headers = {
'Content-Type': 'application/json',
'Charset': 'utf-8',
};
Your api return you a html instead of json, you can do this to avoid getting FormatException:
http.Response response = await http.post(
Uri.parse(url + 'testMe.php'),
headers: headers,
body: body,
);
print('response ${response}');
if (response.statusCode == 200) {
json.decode(response.body);
} else {
print('Response is empty...');
}
usually when statuscode is 500 or 404 this happened, when you check for status code 200, you can avoid getting this FormatException.
Also you don't need to encode the response and decode it again, your response is already encoded in server side, just decode it.

Post Files to ASPNetCore API IFormFile Type

I want to send data with files to AspNetCore api that receive files type IFormFile I tried this
Dio dioFile = Dio(
BaseOptions(
baseUrl: baseUrl,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ${APIVariables.token}',
},
),
);
dioFile.post(
url,
data: {
"id": complaint.id,
"title": complaint.title,
"files": complaint.files
.map((file) => base64Encode(file.readAsBytesSync()))
.toList(),
};
);
but it shows dio error: DioError [DioErrorType.response]: Http status error [400].
How can I solve that and is there another better method to do that?
And if I want to send files using MultipartFile how can I do that and what api specialist should do to handle my post?
If you want to send the image file then,
It should look like this.
String fileName = imageFile.path.split('/').last;
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //important
),
});
If without this line.
contentType: new MediaType("image", "jpeg")
Maybe it will cause an error: DioError [DioErrorType.RESPONSE]: Http status error [400] Exception
You must confirm the correct contentType to work it as expected
And get MediaType in this package: http_parser

Error http 422 and XMLHttpRequest in flutter

I want to connect to a web service. When I use postman, request send and response receive successfully. But in the flutter app, I get error 422 in the android emulator. And with the same code in flutter web, I get XMLHttpRequest error.
My postman:
This is my data that send to the server:
var data = {
"username": usernameController.text,
"password": passwordController.text,
"email": emailController.text
};
And send a request with dio:
Response response = await client
.post(theUrl,
options: Options(headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.acceptHeader:"*/*"
}),
data: jsonEncode(data))
.timeout(const Duration(seconds: 10));
I get errors on this method:
on DioError catch (error) {
var statusCode = error.response?.statusCode;
print("+++++++++++++++" + statusCode.toString());
print("+++++++++++++++" + error.message);
}
How can I fix these errors?
I Added this code to options in dio and Error 422 in mobile is fixed:
Options(
validateStatus: (status) {
return status! < 500;
},
followRedirects: false,
...)
But I still get error XMLHttpRequest in flutter web.

Http Post is working in Postman, but not Flutter

edit: I found the solution and answered the question.
I'm trying POST to Instagram's API in my app. The POST works fine in Postman, but in my flutter code I always get a error response: {error_type: OAuthException, code: 400, error_message: Invalid platform app} . I must be doing something wrong in my flutter POST but I can't figure out what.
Here is my Postman POST (that works every time) along with the correct body response:
And here is my Dart/Flutter code that gives me the error:
var clientID = '708XXXXXXXX';
var clientSecret = '37520XXXXXXXXXXXXX';
var grantType = 'authorization_code';
var rediUrl = 'https://httpstat.us/200';
var urlTwo = 'https://api.instagram.com/oauth/access_token';
var body = json.encode({
'client_id': clientID,
'client_secret': clientSecret,
'grant_type': grantType,
'redirect_uri': rediUrl,
'code': _accessCode
});
print('Body: $body');
var response = await http.post(urlTwo,
headers: {
'Accept': '*/*',
'Content-Type': 'application/json',
},
body: body,
);
print(json.decode(response.body));
I read about the error on a different thread and they say to post as x-www-formurlencoded.. When I switch the Content-Type to this, I get the same error.
The error I get in Flutter:
{error_type: OAuthException, code: 400, error_message: Invalid platform app}
I triple checked and I am using all the same value in Postman and Flutter. I've tried the values as Strings and numbers.
When I print body:
Body: {"client_id":"70000edited","client_secret":"37520634edited","grant_type":"authorization_code","redirect_uri":"https://httpstat.us/200","code":"AQCs-H3cIU0aF1o2KkltLuTmVMmJ-WJnZIhb9ryMqYedited"}
try this once
final response = await http.post(urlTwo,
body: body,
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
encoding: Encoding.getByName("utf-8"));
I've finally got it working using a Map. Which is weird because other attempts I also used a map (I've been trying numerous stack overflow answers). Anyways, here is the working code I used:
var urlTwo = 'https://api.instagram.com/oauth/access_token';
var clientID = '7080000';
var clientSecret = '375XXXXXX';
var grantType = 'authorization_code';
var rediUrl = 'https://httpstat.us/200';
var map = new Map<String, dynamic>();
map['client_id'] = clientID;
map['client_secret'] = clientSecret;
map['grant_type'] = grantType;
map['redirect_uri'] = rediUrl;
map['code'] = _accessCode;
http.Response response = await http.post(
urlTwo,
body: map,
);
var respData = json.decode(response.body);
print(respData);

Dio - Flutter Image Upload returning Socket Exception

I have tried uploading image using formData which Dio plugin supports.
FormData formData = new FormData.from(
{"profile_image": UploadFileInfo(image, "profile_image.jpg")});
var response = await _dio.post(ApiConfiguration.getUploadImageUrl().toString(),data: formData);
But its returning error.
DioError [DioErrorType.DEFAULT]: SocketException: OS Error: Connection reset by peer, errno = 54, address = 3.122.199.93, port = 62181
Any help would be appreciated.
UploadFileInfo and FormData.from deprecated in v3. Documentation needs to be clearer and updated. I wasted a good part of a day with this.
I used dio for post a file path with some other information in this way :
Dio dio = new Dio();
FormData formData = new FormData();
formData.add(
"apiKey",
"my_api_key",
);
formData.add(
"file",
"image_path",
);
Response response = await dio.post(
"https://localhost",
data: formData,
onSendProgress: (int sent, int total) {
// do something
},
).catchError((onError) {
throw Exception('something');
});
Faced something similar in Release version of the app, Dio was failing to upload images. This could be due to two reasons, one is mentioned above that you are using a deprecated methods in v3 or You can try adding this permission to the Manifest
Add this permission
<uses-permission android:name="android.permission.INTERNET" />
to your app level Manifest.
android/app/src/main/AndroidManifest.xml
Solution can be found here
https://stackoverflow.com/a/59392036/14641365
Although the other work around to upload an image to the server that I used is something as follows
String url = "YOUR_URL_TO_UPLOAD";
FormData formData = FormData.fromMap({
"QUERY_PARAM_NAME": await MultipartFile.fromFile("IMAGE_PATH", filename:"TESTING.jpg"),
});
var response = await dio.post(url, data: formData);