How to read Http response from flutter? - http

I'm trying to read reponse from HTTP in flutter but I didnt read.
I posted the request. Can anyone know, what is wrong ?
final http.Client client;
Future<http.Response> post(
Uri uri, {
Map<String, dynamic> postParams,
String accessToken,
}) async {
log.info(uri.toString());
log.info('postParams: ${postParams?.toString()}');
///Encode map to bytes
String jsonString = json.encode(postParams);
List<int> bodyBytes = utf8.encode(jsonString);
Map headers = {
HttpHeaders.contentTypeHeader: 'application/json; charset=utf-8',
};
final response = await client
.post(
uri,
body: bodyBytes,
headers: headers,
)
.timeout(Duration(seconds: 120));
}

You can achieve this functionality as follow
1.install http package and import it as follow
import 'package:http/http.dart' as http;
Create an instance of http or http.Client as you did
final http.Client _client = http.Client();
Send the request to server as follow
var url = 'https://example.com/store/.....';
final Map<String, dynamic> data= {"name":"John Doe", "email":"johndoe#email.com"};
final Map<String, String> _headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
var response = await _client.post(url, body:data, headers:_headers);
Then you can read the response as
if(response.statusCode == 200) {
var decoded = json.decode(response.body);
print(decoded);
// The Rest of code
}

Related

Flutter PARAMS on Get http

How to Put a PARAMS on GET function,
I did not find anything in the documentation of the dart or flutter about this
String url = 'xxxxxx';
Future<String> makeRequest() async {
Map params = {
"anunciante_name"
"anunciante_pass"
"anunciante_email"
};
var _body = jsonDecode(params);
var response = await http
.get(Uri.encodeFull(url), headers: {"Content-type": "application/json", "key": "xxxxx", "token": "xxxxx"},);
print(response.body);
According to the documentation for the get method of the http object,
Future<Response> get (dynamic url, {Map<String, String> headers})
the second parameter is the headers. You can pass each parameter of yours to it as a value the same way you pass your key, token and Content-Type
Map<String, String> reqHeaders = {
"Content-type": "application/json",
"key": "xxxxx",
"token": "xxxxx",
"anunciante_name":name,
"anunciante_pass":password,
"anunciante_email":email
};
var response = await http.get(Uri.encodeFull(url), {headers: reqHeaders});

How 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.
This is what I'm doing:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
postTest() async {
final uri = 'https://na57.salesforce.com/services/oauth2/token';
var requestBody = {
'grant_type':'password',
'client_id':'3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL',
'client_secret':'42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42',
'username':'example#mail.com.us',
'password':'ABC1234563Af88jesKxPLVirJRW8wXvj3D'
};
http.Response response = await http.post(
uri,
body: json.encode(requestBody),
);
print(response.body);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Container(
child: Center(
child: RaisedButton(
child: Text('Press Here'),
onPressed: (){
postTest();
},
),
),
),
);
}
}
This is the actual response:
{
"error": "unsupported_grant_type",
"error_description": "grant type not supported"
}
This is the expected response:
{
"access_token": "00D0b000000Bb08!AR8AQO.s8mAGXCbwV77FXNLQqc2vtl8g6_16miVbgWlQMsuNHsaf2IGLUwnMVXBOfAj19iznhqhwlPOi4tagvf7FFgiJJgoi",
"instance_url": "https://na57.salesforce.com",
"id": "https://login.salesforce.com/id/00D0b000000Bb08EAC/0050b000005nstiAAA",
"token_type": "Bearer",
"issued_at": "1567993324968",
"signature": "1+Zd/dSh9i7Moh2U0nFJLdXkVHqPlPVU6emwdYzXDPk="
}
You can test this on postman switching the body between raw (you get the actual response) and form-data (you get the expected response)
PS: The headers are temporary headers created by the client tool.
Use Map instead, because body in http package only has 3 types: String, List or Map. Try this:
final uri = 'https://na57.salesforce.com/services/oauth2/token';
var map = new Map<String, dynamic>();
map['grant_type'] = 'password';
map['client_id'] = '3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL';
map['client_secret'] = '42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42';
map['username'] = 'example#mail.com.us';
map['password'] = 'ABC1234563Af88jesKxPLVirJRW8wXvj3D';
http.Response response = await http.post(
uri,
body: map,
);
There is a dart package dio
it works like a charm, am using it as a standard to do http requests.
Please read the docs too on sending form data with dio package
import 'package:dio/dio.dart';
postData(Map<String, dynamic> body)async{
var dio = Dio();
try {
FormData formData = new FormData.fromMap(body);
var response = await dio.post(url, data: formData);
return response.data;
} catch (e) {
print(e);
}
}
Use MultipartRequest class
A multipart/form-data request automatically sets the Content-Type header to multipart/form-data.
This value will override any value set by the user.
refer pub.dev doc here
For example:
Map<String, String> requestBody = <String,String>{
'field1':value1
};
Map<String, String> headers= <String,String>{
'Authorization':'Basic ${base64Encode(utf8.encode('user:password'))}'
};
var uri = Uri.parse('http://localhost.com');
var request = http.MultipartRequest('POST', uri)
..headers.addAll(headers) //if u have headers, basic auth, token bearer... Else remove line
..fields.addAll(requestBody);
var response = await request.send();
final respStr = await response.stream.bytesToString();
return jsonDecode(respStr);
Hope this helps
So, you wanna send the body as form-data right? maybe you can try this? for me it's work
postTest() async {
final uri = 'https://na57.salesforce.com/services/oauth2/token';
var requestBody = {
'grant_type':'password',
'client_id':'3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL',
'client_secret':'42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42',
'username':'example#mail.com.us',
'password':'ABC1234563Af88jesKxPLVirJRW8wXvj3D'
};
http.Response response = await http.post(
uri,
body: requestBody,
);
print(response.body);
}
Or
postTest() async {
final uri = 'https://na57.salesforce.com/services/oauth2/token';
http.Response response = await http.post(
uri, body: {
'grant_type':'password',
'client_id':'3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL',
'client_secret':'42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42',
'username':'example#mail.com.us',
'password':'ABC1234563Af88jesKxPLVirJRW8wXvj3D'
});
print(response.body);
}
Edit 1 (this worked for code login flow):
String url = "https://login.salesforce.com/services/oauth2/token";
http.post(url, body: {
"grant_type": "authorization_code",
"client_id": "some_client_id",
"redirect_uri": "some_redirect_uri",
"code": "some_code_generated_by_salesforce_login",
"client_secret": "some_client_secret",
}).then((response) {
//--handle response
});
give 'FormData' a try from:
import 'package:dio/dio.dart';
FormData formData = new FormData.fromMap(dataMap);
retrofitClient.getToken(formData).then((response){//--handle respnse--});
'retrofitClient' is from package
retrofit: ^1.0.1+1
Can you try this;
String url = 'https://myendpoint.com';
Map<String, String> headers = {
"Content-Type": "application/x-www-form-urlencoded"
"Content-type": "application/json"};
String json = '{"grant_type":"password",
"username":"myuser#mail.com",
"password":"123456"}';
// make POST request
Response response = await post(url, headers: headers, body: json);
// check the status code for the result
int statusCode = response.statusCode;
// this API passes back the id of the new item added to the body
String body = response.body;
This is my example with form data function
Future<ResponseModel> postWithFormData(String url, List<File> files,
{Map<String, String> body = const {}, bool throwAlert = false}) async {
var request = http.MultipartRequest("POST", Uri.parse(localApiHost + url));
request.headers
.addAll({"Authorization": "Bearer ${Storage.getString(token)}"});
request.fields.addAll(body);
for (var file in files) {
request.files.add(await http.MultipartFile.fromPath("files", file.path));
}
var sendRequest = await request.send();
var response = await http.Response.fromStream(sendRequest);
final responseData = json.decode(response.body);
if (response.statusCode >= 400 && throwAlert) {
showErrorDialog(responseData["message"]);
}
return ResponseModel(body: responseData, statusCode: response.statusCode);
}
HTTP does not support form-data yet!
Use DIO instead. It will handle everything on its own!
This code snippets successfully executes a POST api call which expect an authorization token and form-data.
final headers = {'Authorization': 'Bearer $authToken'};
var requestBody = {
'shopId': '5',
'fromDate': '01/01/2021',
'toDate': '01/10/2022',
};
final response = await http.post(
Uri.parse(
'https://api.sample.com/mobile/dashboard/getdetails'),
headers: headers,
body: requestBody,
);
print("RESPONSE ${response.body}");
Using POSTMAN to test the query and get the format is quite useful. This is allow you to see if you really need to set Headers. See my example below. I hope it helps and it is not too much
import 'dart:convert';
import 'package:http/http.dart';
class RegisterUser{
String fullname;
String phonenumber;
String emailaddress;
String password;
Map data;
RegisterUser({this.fullname, this.phonenumber, this.emailaddress, this.password});
Future<void> registeruseraction() async {
String url = 'https://api.url.com/';
Response response = await post(url, body: {
'fullname' : fullname,
'phonenumber' : phonenumber,
'emailaddress' : emailaddress,
'password' : password
});
print(response.body);
data = jsonDecode(response.body);
}
}
You can also use MultiPartRequest, it will work for sure
var request = new
http.MultipartRequest("POST",Uri.parse("$baseUrl/example/"));
request.headers.addAll(baseHeader);
request.fields['id'] = params.id.toString();
request.fields['regionId'] = params.regionId.toString();
request.fields['districtId'] = params.districtId.toString();
http.Response response = await http.Response.fromStream(await
request.send());
print('Uploaded! ${response.body} ++ ${response.statusCode}');
import 'package:http/http.dart' as http;
// Function to make the POST request
Future<http.Response> post(String url, Map<String, String> body) async {
// Encode the body of the request as JSON
var encodedBody = json.encode(body);
// Make the POST request
var response = await http.post(url,
headers: {"Content-Type": "application/json"}, body: encodedBody);
// Return the response
return response;
}

Flutter Dart - How to send a Post Request using HttpClient()

I am trying to send a Post request to my server using HttpClient but I am not sure where to actually set the payload and headers that need to be sent.
var client = new HttpClient();
client.post(host, port, path);
client.post(host, port, path) has only 3 arguments so how do I set the payload to be sent?
Thanks in advance
post() opens a HTTP connection using the POST method and returns Future<HttpClientRequest>.
So you need to do this:
final client = HttpClient();
final request = await client.post(host, port, path);
request.headers.set(HttpHeaders.contentTypeHeader, "plain/text"); // or headers.add()
final response = await request.close();
Example with jsonplaceholder:
final client = HttpClient();
final request = await client.postUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"));
request.headers.set(HttpHeaders.contentTypeHeader, "application/json; charset=UTF-8");
request.write('{"title": "Foo","body": "Bar", "userId": 99}');
final response = await request.close();
response.transform(utf8.decoder).listen((contents) {
print(contents);
});
prints
{
"title": "Foo",
"body": "Bar",
"userId": 99,
"id": 101
}
Or you can use http library.
String url =
'http://wwww.foo.com';
http.get(url).then((http.Response response) {
is_loading=true;
// print(json.decode(response.body));
Map<String, dynamic> Data = json.decode(response.body);
Data.forEach((String data, dynamic data_value) {
print(data + " : ");
print(data_value.toString());
// Map<String,String> decoded_data=json.decode(data);
// print(data_value.toString());
//print(data['title']);
//print(data['content']);
});

Flutter http headers

The post request is throwing an error while setting the header map.
Here is my code
Future<GenericResponse> makePostCall(
GenericRequest genericRequest) {String URL = "$BASE_URL/api/";
Map data = {
"name": "name",
"email": "email",
"mobile": "mobile",
"transportationRequired": false,
"userId": 5,
};
Map userHeader = {"Content-type": "application/json", "Accept": "application/json"};
return _netUtil.post(URL, body: data, headers:userHeader).then((dynamic res) {
print(res);
if (res["code"] != 200) throw new Exception(res["message"][0]);
return GenericResponse.fromJson(res);
});
}
but I'm getting this exception with headers.
══╡ EXCEPTION CAUGHT BY GESTURE ╞═
flutter: The following assertion was thrown while handling a gesture:
flutter: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, String>'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 NetworkUtil.post1 (package:saranam/network/network_util.dart:50:41)
flutter: #1 RestDatasource.bookPandit (package:saranam/network/rest_data_source.dart:204:21)
Anybody facing this issue? I didn't find any clue with the above log.
Try
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': '<Your token>'
};
You can try this:
Map<String, String> get headers => {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer $_token",
};
and then along with your http request for header just pass header as header
example:
Future<AvatarResponse> getAvatar() async {
var url = "$urlPrefix/api/v1/a/me/avatar";
print("fetching $url");
var response = await http.get(url, headers: headers);
if (response.statusCode != 200) {
throw Exception(
"Request to $url failed with status ${response.statusCode}: ${response.body}");
}
var avatar = AvatarResponse()
..mergeFromProto3Json(json.decode(response.body),
ignoreUnknownFields: true);
print(avatar);
return avatar;
}
I have done it this way passing a private key within the headers. This will also answer #Jaward:
class URLS {
static const String BASE_URL = 'https://location.to.your/api';
static const String USERNAME = 'myusername';
static const String PASSWORD = 'mypassword';
}
In the same .dart file:
class ApiService {
Future<UserInfo> getUserInfo() async {
var headers = {
'pk': 'here_a_private_key',
'authorization': 'Basic ' +
base64Encode(utf8.encode('${URLS.USERNAME}:${URLS.PASSWORD}')),
"Accept": "application/json"
};
final response = await http.get('${URLS.BASE_URL}/UserInfo/v1/GetUserInfo',
headers: headers);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
return new UserInfo.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data!');
}
}
}
Try this
Future<String> createPost(String url, Map newPost) async {
String collection;
try{
Map<String, String> headers = {"Content-type": "application/json"};
Response response =
await post(url, headers: headers, body: json.encode(newPost));
String responsebody = response.body;
final int statusCode = response.statusCode;
if (statusCode == 200 || statusCode == 201) {
final jsonResponse = json.decode(responsebody);
collection = jsonResponse["token"];
}
return collection;
}
catch(e){
print("catch");
}
}
Future<String> loginApi(String url) async {
Map<String, String> header = new Map();
header["content-type"] = "application/x-www-form-urlencoded";
header["token"] = "token from device";
try {
final response = await http.post("$url",body:{
"email":"test#test.com",
"password":"3efeyrett"
},headers: header);
Map<String,dynamic> output = jsonDecode(response.body);
if (output["status"] == 200) {
return "success";
}else{
return "error";
} catch (e) {
print("catch--------$e");
return "error";
}
return "";
}
void getApi() async {
SharedPreferences prefsss = await SharedPreferences.getInstance();
String tokennn = prefsss.get("k_token");
String url = 'http://yourhost.com/services/Default/Places/List';
Map<String, String> mainheader = {
"Content-type": "application/json",
"Cookie": tokennn
};
String requestBody =
'{"Take":100,"IncludeColumns":["Id","Name","Address","PhoneNumber","WebSite","Username","ImagePath","ServiceName","ZoneID","GalleryImages","Distance","ServiceTypeID"],"EqualityFilter":{"ServiceID":${_radioValue2 != null ? _radioValue2 : '""'},"ZoneID":"","Latitude":"${fav_lat != null ? fav_lat : 0.0}","Longitude":"${fav_long != null ? fav_long : 0.0}","SearchDistance":"${distanceZone}"},"ContainsText":"${_txtSearch}"}';
Response response = await post(url , headers: mainheader ,body:requestBody);
String parsedata = response.body;
var data = jsonDecode(parsedata);
var getval = data['Entities'] as List;
setState(() {
list = getval.map<Entities>((json) => Entities.fromJson(json)).toList();
});
}

Why dio posts empty form data?

I have a function to upload an image but the server does not receive anything and I get 500 status code. I'm sure that the server is fine. It works when I send a post request from the postman!
This is my function:
uploadPrescriptionToAll(File file, data) async {
String convertedFilePath = await convertImage(file);
String token = await getToken();
Response response;
Dio dio = Dio();
dio.options.baseUrl = "http://x.x.x.x:x";
FormData formData = FormData.from({
"image":
UploadFileInfo(new File(convertedFilePath), "image.jpg"),
"data": data,
});
try {
response = await dio.post("/api/images",
data: formData,
options: Options(headers: {
"Authorization": token,
"Content-Type": "multipart/form-data"
}));
} catch (e) {
print("Error Upload: " + e.toString());
}
print("Response Upload:" + response.toString());
}
how can I post the file (form-data) correctly? Is there another way to do it?
Using Dio It's very simple by using : FormData.fromMap()
searchCityByName(String city) async {
Dio dio = new Dio();
var a = {"city": city};
var res = await dio.post(apiSearchState, data:FormData.fromMap(a));
}
In short, you should pass a Map<String, dynamic> object to dio.post()'s data field. For example:
response = await dio.post("/api/images",
data: {"image": "image.jpg", "data": data});
See: https://github.com/flutterchina/dio/issues/88 for details

Resources