Response body is empty in http call - flutter

I am calling a remote PHP file to get some data into my Flutter app.
This is the Flutter function:
Future<void> registrarUsuario() async {
var url = Constantes.adminUsuariosUrl + 'nuevo_usuario.php';
final response = await http.post(Uri.parse(url), body: {
"email": controllerEmail.text,
"password": controllerPass.text
});
print("response ${response.body}");
}
Calling the function the print output is empty.
flutter: response
But calling the PHP file using Postman gives me the following output:
[{"id":"57","correo":"modestovasco#gmail.com"}]
I would like to update the funtion registrarUsuario to get the json objects from the response.body

Encode the body content in request
Future<void> registrarUsuario() async {
var url = Constantes.adminUsuariosUrl + 'nuevo_usuario.php';
final response = await http.post(Uri.parse(url), body:json.encode({
"email": controllerEmail.text,
"password": controllerPass.text
}));
print("response ${response.body}");
}

Related

How to make a http post using form data in flutter

I'm trying to do a http post request and I need to specify the body as form-data, because the server don't take the request as raw or params.
here is the code I tried
** Future getApiResponse(url) async {
try {
// fetching data from the url
final response = await http.get(Uri.parse(url));
// checking status codes.
if (response.statusCode == 200 || response.statusCode == 201) {
responseJson = jsonDecode(response.body);
// log('$responseJson');
}
// debugPrint(response.body.toString());
} on SocketException {
throw FetchDataException(message: 'No internet connection');
}
return responseJson;
}
}
but its not working. here is the post man request
enter image description here
its not working on parms. only in body. its because this is in form data I guess.
how do I call form data in flutter using HTTP post?
First of all you can't send request body with GET request (you have to use POST/PUT etc.) and you can use Map for request body as form data because body in http package only has 3 types: String, List or Map. Try like this:
var formDataMap = Map<String, dynamic>();
formDataMap['username'] = 'username';
formDataMap['password'] = 'password';
final response = await http.post(
Uri.parse('http/url/of/your/api'),
body: formDataMap,
);
log(response.body);
For HTTP you can try this way
final uri = 'yourURL';
var map = new Map<String, dynamic>();
map['device-type'] = 'Android';
map['username'] = 'John';
map['password'] = '123456';
http.Response response = await http.post(
uri,
body: map,
);
I have use dio: ^4.0.6 to create FormData and API Calling.
//Create Formdata
formData = FormData.fromMap({
"username" : "John",
"password" : "123456",
"device-type" : "Android"
});
//API Call
final response = await (_dio.post(
yourURL,
data: formData,
cancelToken: cancelToken ?? _cancelToken,
options: options,
))

POST call works on Postman but not on Flutter

Future<String> loginUser(User user) async {
var body = jsonEncode({
'strlogin': user.email,
});
Response response = await post(SeguriSignAPIURL.loginUser,
headers: headers,
body: body);
if (response.statusCode == 200) {
var decode = jsonDecode(response.body);
return decode['token'];
} else {
print(response.reasonPhrase);
return '';
}
Hey! When I make this Post call on Postman I get a result, however when I run this code on flutter I get a 400 error. My headers:
final headers = {
'Content-Type': 'application/json; charset=UTF-8',
"Accept": "application/json",
};
Postman:
In Postman you do the request using form-data, but in your Flutter code, you pass json-encoded body.
You either need to use form-data in Flutter or update your server code to accept json content type.

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;
}

I am having an error while trying to make a get request on flutter

String url = 'http://localhost:9000/user/john.doe#email.com';
Future<String> get makeRequest() async {
var response = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application"});
print(response.body);
}
I get an error on makeRequests() that says "This function has a return type of 'Future', but doesn't end with a return statement."
You have to return data corresponding to the return type of the function.
String url = 'http://localhost:9000/user/john.doe#email.com';
Future<String> get makeRequest() async
{
var response = await http.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
print(response.body);
return(response.body);
}
You must return a String in the function with the header Future< String >. You probably want to return response.body

How To deal with Response after post request dart httpClient

So I was having issues with flutter http package when it came to making a post request so I used dart HttpClient. I made a post request according to what was described somewhere but I am having issues getting response. Here is my code
Future<HttpClientResponse> submit() async {
print('start');
Map<String, dynamic> data = { 'title' : 'My first post' };
String jsonString = json.encode(data); // 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().postUrl(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
// it's polite to send the body length to the server
request.headers.set('Content-Length', bodyBytes.length.toString());
request.headers.set('Content-Type', 'application/json');
request.add(bodyBytes);
print('done');
return await (request.close());
}
How do I get the response from this request?
HttpClientResponse response = await request.close();
response.transform(utf8.decoder).listen((contents) {
print(data); // <- response content is here
});
This will return HttpCLientResponse, more info https://api.dartlang.org/stable/2.6.1/dart-io/HttpClient-class.html
I have found this from the docs
new HttpClient().get('localhost', 80, '/file.txt')
.then((HttpClientRequest request) => request.close())
.then((HttpClientResponse response) {
response.transform(utf8.decoder).listen((contents) {
// handle data
});
});
Or Use http library
I have create a common method which can handle all get Request,
Future<String> getRequest([var endpoints, var queryParameters]) async {
var uri = Uri.https(NetworkUrl.BASE_URL_1, endpoints, queryParameters);
uri.replace(queryParameters: queryParameters);
var response =
await http.get(Uri.encodeFull(uri.toString()));
//Retrun reponse here
if (response.statusCode == 200) return response.body;
}
To get a response from the above method,
Future<String> deletePostApi() async {
await NetworkRepository()
.getRequest(NetworkUrl.deletePost + '${widget.mFeedData.post_id}')
.then((value) {// <=value is json respone
var dataConvertedToJSON = json.decode(value);
print("checkEmailResp" + dataConvertedToJSON.toString());
});
}