Flutter PARAMS on Get http - 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});

Related

How to send nested Json in body as http post request from Flutter

I'm trying to send a nested Json as body in one of the http post request from the flutter app I had been working on.
{
"user" : {
"UserName": "username",
"password":"password",
"Name": "name",
"Email": "email"
}
}
I tried many methods that were available online to do it, but every time I'm getting a 500 error. Below is a class to convert it into Json.
class SignupJson {
String username;
String email;
String name;
String password;
SignupJson(this.email, this.name, this.password, this.username);
Map toJson() =>{"user":{
'UserName': username,
'Name': name,
'password': password,
'Email': email
}};
}
And pass on it to this for a post request. (I've put an arbitrary url link)
Future<int> attemptSignup ({String username, String password, String name, String email}) async {
SignupJson data = SignupJson(username: username, password: password, name: name, email: email);
var url = 'url';
String body = jsonEncode(json);
var res = await http.post(url,
body: body);
return res.statusCode;
}
Add header like this:
Map<String, String> headers = {HttpHeaders.contentTypeHeader: "application/json"};
then in post request:
var res = await http.post(url, headers: headers, body: body);
Define map as <String, dynamic> e.g. :
Map<String, dynamic> data = {
"User": {
"UserName":"username",
"Password":"password"
}
};
and add the following to the headers :
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('Accept', 'application/json');
request.headers.set('Content-type', 'application/json');
request.add(utf8.encode(json.encode(data)));
HttpClientResponse response = await request.close();
String reply = await utf8.decoder.bind(response).join();
httpClient.close();
I have been stuck in this issue for last 2days. Below is the way how I overcome from my problem
Future<int> attemptSignup ({String username, String password, String name, String email}) async {
SignupJson data = SignupJson(username: username, password: password, name: name, email: email);
var url = 'url';
String body = jsonEncode(data);
//here jsonEncode(data) return String bt in http body you are passing Map value
//So you have to convert String to Map
Map bodyMap = jsonDecode(body);
// your nested json data
var bodyData = { // where var store <String, dynamic> data as your demand
"user" : bodyMap
};
var res = await http.post(url,
body: bodyData,
headers: {"Content-Type": "application/json",},
);
return res.statusCode;
}
make sure to add header in http
I code according to this json:
{
"user": {
"UserName": "username",
"password": "password",
"Name": "name",
"Email": "email"
}
}
Your Post Api call be like:
Future<User> postUser(String username, String password, String name, String
email) async {
Paste your api url here
String url = '';
final response = await http.post(apiUrl, headers: {
// Enter your headers parameter if needed
// E.g:
'Authorization' : 'xyz',
'Content-Type' : 'application/json'
},
body: jsonEncode(<String, String>{
'UserName' : username,
'password' : password,
'Name' : name,
'Email' : email
}));
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data);
return User.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to post user.');
}
}
Your model be like:
class User {
User? user;
User({this.user});
User.fromJson(Map<String, dynamic> json) {
user = json['user'] != null ? new User.fromJson(json['user']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user != null) {
data['user'] = this.user!.toJson();
}
return data;
}
}
class User {
String? userName;
String? password;
String? name;
String? email;
User({this.userName, this.password, this.name, this.email});
User.fromJson(Map<String, dynamic> json) {
userName = json['UserName'];
password = json['password'];
name = json['Name'];
email = json['Email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['UserName'] = this.userName;
data['password'] = this.password;
data['Name'] = this.name;
data['Email'] = this.email;
return data;
}
}
Since this is as yet unanswered, I'll take a stab. I've spent the same time as others troubleshooting against this issue and it's very frustrating.
What I learned is that the point of the content-type header is that it changes how Client.post structures the body as is creates the request, in addition to informing the server what type of data to expect. In my case, I had it erroneously set to 'application/x-www-form-urlencoded' which was working for other routes that I was passing individual maps of single-level objects and classes to, but it was failing on anything that had a key which had an object attached.
If I tried to pass a map on the key, it earned:
Expected a value of type 'String', but got one of type 'IdentityMap<String, dynamic>'.
and when I set the header properly but passed a map instead of a json.encode'ed map, I got:
Bad state: Cannot set the body fields of a Request with content-type "application/json".
From the Dart documentation for the post function:
Sends an HTTP POST request with the given headers and body to the
given URL.
body 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".
If body is a List, it's used as a list of bytes for the body of the
request.
If body is a Map, it's encoded as form fields using encoding. The
content-type of the request will be set to
"application/x-www-form-urlencoded"; this cannot be overridden.
So we can see that if the specific header for content-type is missing OR if the content-type is set to application/json AND a map is passed to the body, the map will cause the post function to override the content-type header and set the header to urlencoded.
So even if the server is not expecting the content-type header, so to speak, it is expecting JSON-encoded data, and the only way to achieve that is to both:
Set the content-type header to application/json AND
Pass a properly json-encoded map (NOT a plain map) as the body parameter using jsonEncode( map ) or json.encode( map ) which are the same thing.

How to read Http response from flutter?

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
}

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']);
});

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