Flutter Chopper does not handle error response - flutter

I am using chopper in my flutter project like this.
AuthRestService class:
import 'package:chopper/chopper.dart';
import 'package:flutter_meal_app/utils/constants.dart';
import 'package:injectable/injectable.dart';
part 'auth_rest_service.chopper.dart';
#prod
#singleton
#ChopperApi()
abstract class AuthRestService extends ChopperService {
#Post(path: '/accounts:signUp?key={authKey}')
Future<Response> signup(#Path('authKey') String authKey, #Body() Map<String, dynamic> body);
#Post(path: '/accounts:signInWithPassword?key={authKey}')
Future<Response> login(#Path('authKey') String authKey, #Body() Map<String, dynamic> body);
#factoryMethod
static AuthRestService create() {
final client = ChopperClient(
baseUrl: Constants.AUTH_BASE_URL,
converter: JsonConverter(),
services: [_$AuthRestService()],
interceptors: [HttpLoggingInterceptor()]);
return _$AuthRestService(client);
}
}
The way I use signup call..
final response = await _authRestService.signup(AUTH_KEY,
{'email': email, 'password': password, 'returnSecureToken': true});
Here is the log of webcall (both success and failure)..
--> POST https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=yourauthkey
content-type: application/json; charset=utf-8
{"email":"palaksdarji#gmail.com","password":"123456","returnSecureToken":true}
--> END POST (78-byte body)
Success:
{
"idToken":"....",
........
}
Failure:
<-- 400 https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=yourauthkey
cache-control: no-cache, no-store, max-age=0, must-revalidate
date: Sat, 17 Oct 2020 09:10:32 GMT
transfer-encoding: chunked
content-encoding: gzip
vary: Origin,X-Origin,Referer
content-type: application/json; charset=UTF-8
pragma: no-cache
x-xss-protection: 0
server: ESF
alt-svc: h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
expires: Mon, 01 Jan 1990 00:00:00 GMT
{
"error": {
"code": 400,
"message": "EMAIL_EXISTS",
"errors": [
{
"message": "EMAIL_EXISTS",
"domain": "global",
"reason": "invalid"
}
]
}
}
--> END POST
And The error I got in my logs is:
error is Instance of 'Response<dynamic>'
I used the same type of RestService in my project which is pointed to another server and It works, this AuthRestService is exact copy of restservice for firebase authentication. The error that I got in my logs is from the line where we call "signup" API, which makes me curious about my ChopperClient.
Do you guys know what is going wrong?? Please help. Thanks.

Maybe you can parse error response like this
Response response = await _authRestService.signup(AUTH_KEY,
{'email': email, 'password': password, 'returnSecureToken': true});
var res = SignUpResponse.fromJson(response.body);
SignUpResponse
part 'sign_up_response.g.dart';
#JsonSerializable()
class SignUpResponse extends BaseResponse {
var error = new Error();
SignUpResponse();
factory SignUpResponse.fromJson(Map<String, dynamic> json) =>
_$SignUpResponseFromJson(json);
Map<String, dynamic> toJason() => _$SignUpResponseToJson(this);
}

Related

How to solve this dio library error? Flutter/Dart

Hello there i am trying to download a pdf file with dio library but in the end i get this errror:
Hello there i am trying to download a pdf file with dio library but in the end i get this errror:
I/flutter (19900): 100%
I/flutter (19900): connection: keep-alive
I/flutter (19900): last-modified: Mon, 17 Oct 2022 10:17:34 GMT
I/flutter (19900): cache-control: no-cache, no-store, max-age=0, must-revalidate
I/flutter (19900): date: Fri, 21 Oct 2022 07:39:15 GMT
I/flutter (19900): vary: Origin
I/flutter (19900): vary: Access-Control-Request-Method
I/flutter (19900): vary: Access-Control-Request-Headers
I/flutter (19900): content-type: text/html;charset=UTF-8
I/flutter (19900): pragma: no-cache
I/flutter (19900): x-xss-protection: 1; mode=block
I/flutter (19900): content-language: en
I/flutter (19900): server: nginx/1.15.12
I/flutter (19900): accept-ranges: bytes
I/flutter (19900): content-length: 6425
I/flutter (19900): x-frame-options: DENY
I/flutter (19900): x-content-type-options: nosniff
I/flutter (19900): expires: 0
I/flutter (19900): FileSystemException: Cannot open file, path = '/data/user/0/com.iccs.electromobilityapp/cache' (OS Error: Is a directory, errno = 21)
Here is my code:
Future download2(Dio dio, String url, String savePath) async {
Directory tempDir = await getTemporaryDirectory();
tempPath = tempDir.path;
String? token = await this.widget.appController.storage.read(key: "token");
Map<String, String> headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer " + (token ?? ""),
};
try {
Response response = await dio.get(
url,
onReceiveProgress: showDownloadProgress,
//Received data with List<int>
options: Options(
headers: headers,
responseType: ResponseType.bytes,
followRedirects: false,
validateStatus: (status) {
return status! < 500;
}),
);
print(response.headers);
new File('$tempPath/file.xlsx').create(recursive: true);
File file = File(tempPath);
var raf = file.openSync(mode: FileMode.write);
// response.data is List<int> type
raf.writeFromSync(response.data);
await raf.close();
} catch (e) {
print(e);
}
}
I've written a simple function for you just pass a url and filename as an argument
downloadedFile({required String url, required String filename}) async {
var downloadsDirectoryPath = await getTemporaryDirectory()
final File file = File("/${downloadsDirectoryPath!.path}/$filename");
final response = await Dio().get(url, onReceiveProgress: (received, total) {
},
options: Options(
responseType: ResponseType.bytes,
followRedirects: false,
receiveTimeout: 0,
));
final raf = file.openSync(mode: FileMode.write);
raf.writeFromSync(response.data);
await raf.close();
return file;
}
Note: upvote and make the answer as correct if you find it useful.

How to pass header in another response in flutter

I have response.header in header. I want to pass that header to another response.
so, my approach is to save the header in shared preference and then retrieve it.
final prefs = await SharedPreferences.getInstance();
prefs.setString('header', response.headers.toString());
and then retrieve it
final prefs = await SharedPreferences.getInstance();
String? head = prefs.getString('header');
Map<String, String> authHeaders = jsonDecode(head!);
but authHeders is giving me an error.
Unhandled Exception: FormatException: Unexpected character (at character 2)
header before saving to SharedPreferences.
{connection: keep-alive, set-cookie: XSRF-TOKEN=nBYdTZyY2FrQUl0RitDemxmdnNVMVRacC9XcENyV3pJankiLCJtYWMiOiJkOTRmZWMwYjYyMDdjMjAwNjBmZTJmZDYyNGYzYzI0YTVjMDNmN2VjZjc3MzZkM2UzNzc1MTk2ZjViOGE0MGMyIiwidGFnIjoiIn0%3D; expires=Mon, 01-Aug-2022 08:56:00 GMT; Max-Age=7200; path=/; samesite=lax,laravel_session=eyJpdiI6Iko1U1ZkejhNWVo3b0twb0pwdS9QMVE9PSIsInZhbHVlIjoiVUxyTFVmMm9XSG95VHd6cGxCVThqSExvSzJQWmQ2WWRMRGpoT0xsVjExdHl1M0xnZ2xGZjd2WDRVdHRqa1J4TU4rRjByakFoSUNHT2lPTGVUb0Z4aHNhWjRleTM0TnBjakRPRzc4WkZVWDMvTzdqNlpoVTBCRWRsOTlwcHIvNFQiLCJtYWMiOiI0MTRhMjRkNGY3Njg0ZDI4NjU1MzFmZjI2M2FkOTA5NDc4ZWJhYzhiZTA5MTFkZTQ2ZmJlY2UxNzBlZjc3MTc3IiwidGFnIjoiIn0%3D; path=/; httponly; samesite=lax, cache-control: no-cache, private, date: Mon, 01 Aug 2022 06:56:00 GMT, vary: Accept-Encoding, content-encoding: gzip, cf-cache-status: DYNAMIC, report-to: {"endpoint .......
header after retrieving it.
{connection: keep-alive, set-cookie: XSRF-TOKEN=nBYdTZyY2FrQUl0RitDemxmdnNVMVRacC9XcENyV3pJankiLCJtYWMiOiJkOTRmZWMwYjYyMDdjMjAwNjBmZTJmZDYyNGYzYzI0YTVjMDNmN2VjZjc3MzZkM2UzNzc1MTk2ZjViOGE0MGMyIiwidGFnIjoiIn0%3D; expires=Mon, 01-Aug-2022 08:56:00 GMT; Max-Age=7200; path=/; samesite=lax,laravel_session=eyJpdiI6Iko1U1ZkejhNWVo3b0twb0pwdS9QMVE9PSIsInZhbHVlIjoiVUxyTFVmMm9XSG95VHd6cGxCVThqSExvSzJQWmQ2WWRMRGpoT0xsVjExdHl1M0xnZ2xGZjd2WDRVdHRqa1J4TU4rRjByakFoSUNHT2lPTGVUb0Z4aHNhWjRleTM0TnBjakRPRzc4WkZVWDMvTzdqNlpoVTBCRWRsOTlwcHIvNFQiLCJtYWMiOiI0MTRhMjRkNGY3Njg0ZDI4NjU1MzFmZjI2M2FkOTA5NDc4ZWJhYzhiZTA5MTFkZTQ2ZmJlY2UxNzBlZjc3MTc3IiwidGFnIjoiIn0%3D; path=/; httponly; samesite=lax, cache-control: no-cache, private, date: Mon, 01 Aug 2022 06:56:00 GMT, vary: Accept-Encoding, content-encoding: gzip, cf-cache-status: DYNAMIC, report-to: {"endpoint .......
Yes, both are same.
This is how I am saving header.
login(String phn, String password) async {
final prefs = await SharedPreferences.getInstance();
await getLocation();
String uri = "$baseUrl/User_Login";
try {
http.Response response = await http.post(Uri.parse(uri), headers: {
'Accept': 'application/json'
}, body: {
"number": phn,
"password": password,
"long": long,
"lati": lati
});
print(response.headers);
prefs.setString('header', response.headers.toString());
return json.decode(response.body);
} catch (e) {
return e;
}
}
This is how I am retrieving it and passing it to another response.
getData() async {
final prefs = await SharedPreferences.getInstance();
String? head = prefs.getString('header');
print("headers");
print(head);
Map<String, String> authHeaders = jsonDecode($head!);
// print("authHeaders");
// print(authHeaders.toString());
String uri = "$baseUrlUser/user_bal";
try {
http.Response response =
await http.get(Uri.parse(uri), headers: authHeaders);
return json.decode(response.body);
} catch (e) {
return e;
}
}
The common issue in Flutter when parsing Json data is about the type of request and it's encoding.
Even if you may post the complete source code, at least, the relevant one to your problem, like how you're performing the request, your error probably comes on how you ask for data to the remote.
If you're trying to parse the response as Json, you must specifically add the application/json;charset=UTF-8 in your headers.
But, if you read this line in your source code:
prefs.setString('header', response.headers.toString());
you're saving the headers as string in the header key. This means, that the headers are usually represented in most standars as Map datastructures, so you're asking for retrive as a String in decode(...) a probably bad formatted data.
The solution it's pretty straightfoward. Save the header(s) that your interested one by one, and then retrieve them by key, and the format should be ok to use the jsonDecode.
Edit:
getting directly your code to exemplify as requested by the OP how to get them individually. We will take the Accept header as example, as it's also the unique provide in the example code.
login(String phn, String password) async {
final prefs = await SharedPreferences.getInstance();
await getLocation();
String uri = "$baseUrl/User_Login";
try {
http.Response response = await http.post(Uri.parse(uri), headers: {
'Accept': 'application/json'
}, body: {
"number": phn,
"password": password,
"long": long,
"lati": lati
});
prefs.setString('header', response.headers.get('Accept'));
return json.decode(response.body);
} catch (e) {
return e;
}
}
Then, you only must retrieve it by key:
getData() async {
final prefs = await SharedPreferences.getInstance();
String? head = prefs.getString('Accept');
Map<String, String> authHeaders = new Map();
authHeaders['Accept'] = head!;
String uri = "$baseUrlUser/user_bal";
try {
http.Response response =
await http.get(Uri.parse(uri), headers: authHeaders);
return json.decode(response.body);
} catch (e) {
return e;
}
}
The unique difference is that you're not storing a completly Map as a String as you do in the example, you're saving the keys that you desire as what they are, Strings. Parsing JSON it's alwaya a quite sensible action, so the more granularity over the pieces you take, the best results.

Getting invalid response on data of api using dio in flutter

i want to pass username and token from login screen to dashboard, i saved it using sharedpreference and call it to dashboard, i'm getting values too. but when i pass them to my api, using dio and print it's response.data it gives me Error wherease it's statuscode is 200. kindly help me with to fix this issue.
here is my code
var localhostUrl="http://10.0.2.2:8000/TimeIn";
_userDetails() async{
SharedPreferences myPrefs=await SharedPreferences.getInstance();
setState(() {
getname=myPrefs.getString('name');
getdesignation=myPrefs.getString('designation');
getTimeInStatus=myPrefs.getBool('timeInStatus');
getaccesstoken=myPrefs.getString('accesstoken');
});
}
calltimeInApi() async {
Dio dio=new Dio(
BaseOptions(
connectTimeout: 30000,
baseUrl: localhostUrl,
responseType: ResponseType.json,
contentType: ContentType.json.toString(),
));
var data={
'username':getname
};
dio.options.headers["authorization"] = "Bearer ${getaccesstoken}";
await dio.post(localhostUrl,data: data).then((onResponse) async {
print(onResponse.headers);
print(onResponse.statusCode);
print(onResponse.data);
;
});}
here is the output
I/flutter (14995): 1
I/flutter (14995): x-powered-by: Express
I/flutter (14995): connection: keep-alive
I/flutter (14995): keep-alive: timeout=5
I/flutter (14995): date: Wed, 09 Jun 2021 18:34:53 GMT
I/flutter (14995): content-length: 7
I/flutter (14995): etag: W/"7-Vuu5vA8hV5HSudFEr8bWQajjaE0"
I/flutter (14995): content-type: application/json; charset=utf-8
I/flutter (14995): 200 //statuscode
I/flutter (14995): Error //data
-----------Updated
i have tried all possible answers which i got from internet but no one resolves my problem
calltimeInApi() async {
Dio dio=new Dio(
BaseOptions(
connectTimeout: 30000,
baseUrl: localhostUrlTimeIn,
headers: {"Accept":"application/json"}
//contentType: ContentType.json.toString(),
));
var data={
"username":getname
};
dio.options.headers["authorization"] = "Bearer ${getaccesstoken}";
await dio.post(localhostUrlTimeIn,data: json.encode(data)).then((onResponse) async {
print(onResponse.headers);
if (onResponse.statusCode == 200) {
print(json.decode(onResponse.data));
} else {
print(onResponse.statusCode);
}
//print(onResponse.statusCode);
//print(json.decode(onResponse.data));
// print(response.statusCode);
// print(response.headers);
// print(response.statusMessage);
// print(response.data);
});}
here are logs of the above updated code
I/flutter (14995): 1
I/flutter (14995): x-powered-by: Express
I/flutter (14995): connection: keep-alive
I/flutter (14995): keep-alive: timeout=5
I/flutter (14995): date: Wed, 09 Jun 2021 19:20:41 GMT
I/flutter (14995): content-length: 7
I/flutter (14995): etag: W/"7-Vuu5vA8hV5HSudFEr8bWQajjaE0"
I/flutter (14995): content-type: application/json; charset=utf-8
E/flutter (14995): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: FormatException: Unexpected character (at character 1)
E/flutter (14995): Error
E/flutter (14995): ^
E/flutter (14995):
-----------------------------------UPDATED-----------------------------
i try to pass token in data, my api is working properly it response successfully according to my requirement but it's still giving me Error on response.data.
here is my update code
calltimeInApi() async {
Dio dio=new Dio();
var data={
'username': getname,
'token': getaccesstoken
};
await dio
.post(localhostUrlTimeIn,data: json.encode(data))
.then((onResponse) async {
print(onResponse.data);
print(onResponse.headers);
print(onResponse.statusCode);
}).catchError((onerror){
print(onerror.toString());
//showAlertDialog(context);
});
}
please help if anyone know how to fix it
//editing your dio
Dio createDio() {
//configure dio
Dio dio = Dio(BaseOptions(
connectTimeout: 50000,
receiveTimeout: 50000,
baseUrl: ApiPaths.BASE_URL,
));
;
//add interceptors
dio.interceptors.add(InterceptorsWrapper(
onRequest: (Options options, handler) async {
print('send request:path:${options.path},baseURL:${options.baseUrl}');
//==============fetch your token and parse it here as csrfToken============
if (csrfToken == null) {
print('no token,request token firstly...');
//lock the dio.
dio.lock();
//token null , try getting new token
handler.next(options);
}).catchError((error, stackTrace) {
handler.reject(error, true);
}) .whenComplete(() => dio.unlock()); // unlock the dio
} else {
//here add your token
options.headers["authorization"] = "Bearer $csrfToken";
handler.next(options);
}
}
));
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(HttpClient client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
final isValidHost = host == ApiPaths.BASE_URL;
return true;
};
return client;
};
return dio;
}
var dioHelper = createDio();
Edit your dio.post to match this . You nolonger need to create dio again. Anywhere you need to access dio use dioHelper
Response response= await dioHelper.post(localhostUrlTimeIn,data: json.encode(data));
print(response.statusCode)
print(response.data)
//you decode when parsing to an object model

Getting Blank httpException message while trying to pass client certificate with dio

I am getting blank httpException message while trying to submit client certificate by using Dio package.
DioErrorType (DioErrorType.DEFAULT) : HttpException (HttpException: , uri = [API_PATH])
Same certificate is working when requesting with postman.
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Thu, 21 Jan 2021 05:56:55 GMT
Below is the code I am using
Future<List<int>> loadCertificate(String assetPath) async {
return (await rootBundle.load(assetPath)).buffer.asUint8List();
}
final List<int> certificateChainBytes =
await loadCertificate('assets/certs/client-cert1.pfx');
final List<int> keyBytes =
await loadCertificate('assets/certs/client-cert1.pfx');
final Dio dio = Dio();
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) {
final SecurityContext sc = SecurityContext()
..useCertificateChainBytes(certificateChainBytes, password: 'Secret')
..usePrivateKeyBytes(keyBytes, password: 'Secret');
final HttpClient httpClient = HttpClient(context: sc);
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
print('badcertificatecallback');
print(cert.issuer);
return true;
};
return httpClient;
};
try {
url = url.contains('http') ? url : '${PsConfig.ps_app_url}$url';
print('API Response from $url');
final Response response =
await dio.get(url, options: Options(headers: getHeaders()));
return processHttpResponse(obj, response);
} on diolib.DioError catch (e) {
inspect(e);
return processDioResponse(obj, e);
} finally {
dio.close();
}
I am new to this and got stuck. Thank you in advance.

How to post x-www-form-urlencoded in Flutter

I am trying to send a POST request to an API to create an account.
The request is working well, it should look like this :
Bulk Edit Mode :
Key-Value Edit mode :
There are also 9 headers that are auto-generated, so I did not show them, but I can take another screen if you need to.
My request looks like this :
import 'dart:convert' as convert ;
import 'package:my_project/requests/utils.dart';
import 'package:http/http.dart' as http;
Future<String> createUser(String firstName, String name, String mail,
String password, String confirmPassword, String birthDate,
String phone) async {
String url = BASE_URL + "createUser" ; // Don't worry about BASE_URL, the final url is correct
Map<String, dynamic> formMap = {
"name": name,
"surname": firstName,
"mail": mail,
"password": password,
"birth": birthDate,
"phone": phone,
"confirmPassword": confirmPassword
} ;
http.Response response = await http.post(
url,
body: convert.jsonEncode(formMap),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
encoding: convert.Encoding.getByName("utf-8"),
);
print("RESPONSE ${response.statusCode} ; BODY = ${response.body}");
return (response.body) ;
}
Here is my print result :
I/flutter ( 6942): RESPONSE 307 ; BODY =
As you can see, I am getting a 307 error, and the problem does not come from the server, as it worked with Postman.
Am I sending this form-urlencoded POST request correctly ?
I also tried :
http.Response response = await http.post(
url,
body: "name=$name&surname=$firstName&mail=$mail&password=$password&birth=$birthDate&phone=$phone&confirmPassword=$confirmPassword",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
encoding: convert.Encoding.getByName("utf-8"),
);
but with the same results. I tried too :
http.Response response = await http.post(
url,
body: formMap,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
encoding: convert.Encoding.getByName("utf-8"),
);
with same result again.
What am I doing wrong ?
EDIT :
I tried FoggyDay answer, here is my request now :
final client = HttpClient() ;
final request = await client.postUrl(Uri.parse(url));
request.headers.set(HttpHeaders.contentTypeHeader, "application/x-www_form-urlencoded");
request.followRedirects = true ;
request.write(formMap);
final response = await request.close();
print("STATUS CODE = ${response.statusCode}");
However I still have a 307 error. Did I create the right request ?
EDIT 2 :
As asked, I printed location as follow :
final client = HttpClient() ;
final request = await client.postUrl(Uri.parse(url));
request.headers.set(HttpHeaders.contentTypeHeader, "application/x-www_form-urlencoded");
request.followRedirects = true ;
request.write(formMap);
final response = await request.close();
print("STATUS CODE = ${response.statusCode}");
print("Response headers = ${response.headers}");
And I get :
I/flutter ( 7671): STATUS CODE = 307
I/flutter ( 7671): Response headers = location: /app/createUser/
I/flutter ( 7671): date: Tue, 26 May 2020 09:00:29 GMT
I/flutter ( 7671): content-length: 0
I/flutter ( 7671): server: Apache/2.4.41 (Amazon) OpenSSL/1.0.2k-fips
The thing is I am already making a call on /app/createUser... ('/app/' is in BASE_URL)
For x-www-form-urlencoded parameters, just use this:
Future<String> login(user, pass) async {
final response = await http.post(
Uri.parse('https:youraddress.com/api'),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
encoding: Encoding.getByName('utf-8'),
body: {"title": "title"},
);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
}
}
official http package from flutter is buggy with urlencoded type, you can use Dio package instead.
final dio = Dio();
final res = dio.post(
'/info',
data: {'id': 5},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
As you can see, I am getting a 307 error, and the problem does not come from the server, as it worked with Postman.
No, that's NOT necessarily the case. Look here:
MDN: 307 Temporary Redirect
In other words, Postman is following the redirect ... and your Flutter app isn't.
SUGGESTION: Try setting followRedirects to true:
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
ADDITIONAL INFO:
The default value for request.followRedirects happens to be "true" anyway. It doesn't hurt to explicitly set it ... but it explains why the behavior didn't change.
Per this post:
The Dart HTTP client won't follow
redirects
for POSTs unless the response code is 303. It follows 302 redirects
for GET or HEAD.
Per this post
The correct way to handle redirects on POST requests is to manually
implement an appropriate strategy for your use case:
var response = await client.post(...);
if (response.statusCode == 301 || response.statusCode == 302) {
// send post request again if appropriate
}
let try with this code, it works well for me.
var headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
var request = http.Request('POST', Uri.parse('https://oauth2.googleapis.com/token'));
request.bodyFields = {
'client_id': '',
'client_secret': '',
'code': '',
'grant_type': 'authorization_code',
'redirect_uri': ''
};
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
If you are using http, you should add the below lines
Android -
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="first_app"
android:usesCleartextTraffic="true" //this line
android:icon="#mipmap/ic_launcher">
iOS -
ios/Runner/info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Be warned that you will need to have an explanation for Apple's review team when enabling this, otherwise, your app will get rejected on submission.
Uninstall the app and Reinstall again if you have the app already in the emulator when you add those lines to avoid confusions.
If you send HTTP GET request, you can use query parameters as follows:
QueryParameters
http://example.com/path/to/page?name=ferret&color=purple
The contents are encoded as query parameters in the URL
application/x-www-form- urlencoded
The contents are encoded as query parameters in the body of the
request instead of the URL.
The data is sent as a long query string. The query string contains
name-value pairs separated by & character
POST example
flutter http package version - http: ^0.13.1
import 'package:http/http.dart' as httpClient;
Future<dynamic> postData() async {
//Uri.https("192.168.1.30:5000", "/api/data")
//Uri.parse("your url");
final Uri uri = Uri.http("192.168.1.30:5000", "/api/data");
final response = await httpClient.post(
uri,
body: {
"name": "yourName",
"age": "yourAge"
},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
encoding: Encoding.getByName('utf-8'),
);
return response.body;
}