JSON.stringify() Equal method in Dart or Flutter - flutter

What is JSON.stringify() Equal method in Dart or Flutter.
Actually my Backend Services Expecting String Object. How I need to convert From JSON to String Like Below.
HTTP Request Method
Future<String> createUser(SignupUser data) async {
NameReq111 req111 = NameReq111(
firstName: 'dfgdfg',
lastName: 'KKK',
email: 'kvr#gmail.com',
phoneNumber: '9704334584');
ReqNameObject reqName = ReqNameObject(data: req111);
var jsncode = jsonEncode(reqName.toMap());
// It Will Print : {data: {fisrtName:Siva, lastName:Joythi,email:kvr#gmail.com, phoneNnumber:9090909090}}
print(json.decode(jsncode));
//It will Print : {"data": {"fisrtName":"Siva", "lastName":"Joythi","email":"kvr#gmail.com", "phoneNnumber":"9090909090"}}
// But Expected Output Will be:
// '{"data": {"fisrtName":"Siva", "lastName":"Joythi","email":"kvr#gmail.com", "phoneNnumber":"9090909090"}}'
final response = await client.post(
"$baseUrl" + "/urlmethoName",
headers: {"content-type": "application/json", 'charset': 'UTF-8'},
body: json.decode(jsncode),
);
if (response.statusCode == 200) {
return response.body;
} else {
return response.body;
}
}
Output:
My Backend Language Expecting below format:
'{"data": {"fisrtName":"Siva", "lastName":"Joythi","email":"kvr#gmail.com", "phoneNnumber":"9090909090"}}'
How we can do that in Flutter.
Could you please help me. Thanks in advance !!!.

Use jsonEncode(obj) to generate a String in json format

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,
))

Incomplete response JSON body with flutter http.Request.send()

I am not sure what is going on with my function. I am trying to have a generic request function that I can use with any request method (GET, POST, etc...). Everything is working well, except for the POST response, it is missing data. I double checked what is expected to be returned and compared it with the response from Postman and my code. My code produces less data than expected and Postman.
Here is what I am doing
class HttpClientHandler {
String baseUrl = 'jsonplaceholder.typicode.com';
String path = '/posts';
static const Map<String, String> defaultHeaders = {'': ''};
static const Map<String, String> defaultBody = {'': ''};
Future<dynamic> request(HttpMethod method,
{Map<String, String> headers = defaultHeaders,
Map<String, dynamic> body}) async {
var uri = Uri.https(baseUrl, '$path');
var request = http.Request(method.type, uri);
request.headers.addAll(headers);
request.body = body.toString();
var response = await request.send();
if (response.statusCode >= 200 && response.statusCode <= 299) {
String rawData = await response.stream.transform(utf8.decoder).join();
return jsonDecode(rawData);
} else {
throw Exception();
}
}
}
The caller simply does the following:
var _client = HttpClientHandler();
var data = await _client.request(HttpMethod.POST, body: {'title': 'foo', 'body': 'bar', 'userId': 1});
print(data);
The response I get is:
{id: 101}
The expected response is:
{
"title": "foo",
"body": "bar",
"userId": "1",
"id": 101
}
I am using import 'package:http/http.dart' as http; package. Is this a stream, transform, or headers issue?
I found what was wrong in my implementation, I didn't jsonEncode my request body. The test API I am using here replies the same request body it receives. Since I wasn't encoding the body correctly, it only was recognizing the first data being sent.
So, the fix is to change this line:
request.body = body.toString();
to this line:
request.body = jsonEncode(body);
Also, I ended up parsing the stream byte to string differently, from:
String rawData = await response.stream.transform(utf8.decoder).join();
To:
String rawData = await response.stream.bytesToString();

how can i send file with api post method?

Here is my post method , i can send anything with text format but i need to send a file.
if you can, modify just my code. that is easy for catch problem, thanks
getComp() async {
final Map<String, dynamic> jsondata = {
'employee_id':
'${ScopedModel.of<AppModel>(context, rebuildOnChange: true).employee_id}',
'receiver_id': '${recid.text}',
'subject': '${subject.text}',
'message_body': '${msgbody.text}',
'message_attachment':'${filePath}'
};
var jsonresponse = null;
var response = await http.post(
'example.com/compose',
headers: {
"Accept": "application/json"
},
body: jsondata,
);
if (response.statusCode == 200) {
jsonresponse = json.decode(response.body);
print(jsonresponse);
}else{
print('problem');
}
}
Here is my file path picker
getfile(){
filePath = FilePicker.getFilePath(type: FileType.ANY);
}
if you can, modify this code .
convert it to base64 first and insert it to the database. That's how I did it when we developed an app that pass a file to the database.
i solve my problem with dio, :(
if anyone face then use dio
uploadFile() async {
FormData formData = new FormData.fromMap({
'employee_id':
'546546',
'receiver_id': '${recid.text}',
'subject': '${subject.text}',
'message_body': '${msgbody.text}',
'message_attachment': filePath ==null? 'nothing': await
MultipartFile.fromFile("${filePath}",filename: "$filePath}"),
});
Response response = await Dio().post("example.com", data: formData);
print(response);
}

How to post a map of string and list with flutter

I am trying to send a Map of string and list which is like:
Map<String, List<int>> results = {
"tags": [5 , 10]
}
Object headers = {
HttpHeaders.authorizationHeader: "Bearer ${accessToken}",
"Accept": "application/json",
};
and I post that like this:
post() {
return http
.post("$resource/$baseName/$id$query",
headers: headers,
body: results ,
)
.then((http.Response response) {
return json.decode(response.body);
}).catchError((err) {
print(err);
});
}
and I got this error:
type 'List<int>' is not a subtype of type 'String' in type cast
also I guess that I should send
Map<String,String>
but I have
Map<String, List<int>>
I try many things but am also new to flutter so I got confusing a lot
Thanks if someone can help me .
EDIT:
i try with dio
try {
Response response =
await Dio().post("$resource/$baseName/$id$query", data: {
'tags': [1, 2]
},
options: Options(headers: headers)
);
print(response);
} catch (e) {
print(e);
}
Are you encoding your data when you send it? Try encoding your data before sending it. You specify your header to accept application/json, but you might not be sending json.
See: https://api.dartlang.org/stable/2.5.0/dart-convert/jsonEncode.html
import 'dart:convert';
Map<String, List<int>> results = {
"tags": [5 , 10]
};
final encodedResults = jsonEncode(results); // send these encoded results.
How do you create this map?
Wouldn't it be possible to start a .toString in the list?
Note: I suggest using the Dio plugin, it makes it much easier to work with requests in webServices, in my opinion of course!
Take a look here: https://pub.dev/packages/dio
Map<String, List<int>> results = {
"tags": [5 , 10]
}
var dio = Dio();
FormData data = FormData();
final local = '$baseName/$id$query'
dio.options.baseUrl = source;
data.add('tags', results.toString);
try{
final response = await dio.post(local, data: data, options: Options(
method: 'POST',
responseType: ResponseType.json
));
final body = jsonDecode(response.data);
print(body);
}catch(e){
print(e);
return e;
}

Flutter: HttpClient post contentLength -- exception

Very weird...
In order to post some JSON data to my server, I define the contentLength to the length of the JSON encoded data but I then receive an exception that says "Content size exceeds specified contentLength". Difference is 1 byte.
Here is the source code:
Future<Map> ajaxPost(String serviceName, Map data) async {
var responseBody = json.decode('{"data": "", "status": "NOK"}');
try {
var httpClient = new HttpClient();
var uri = mid.serverHttps ? new Uri.https(mid.serverUrl, _serverApi + serviceName)
: new Uri.http(mid.serverUrl, _serverApi + serviceName);
var request = await httpClient.postUrl(uri);
var body = json.encode(data);
request.headers
..add('X-mobile-uuid', await _getDeviceIdentity())
..add('X-mobile-token', await mid.getMobileToken());
request.headers.contentLength = body.length;
request.headers.set('Content-Type', 'application/json; charset=utf-8');
request.write(body);
var response = await request.close();
if (response.statusCode == 200){
responseBody = json.decode(await response.transform(utf8.decoder).join());
//
// If we receive a new token, let's save it
//
if (responseBody["status"] == "TOKEN"){
await mid.setMobileToken(responseBody["data"]);
// Let's change the status to "OK", to make it easier to handle
responseBody["status"] = "OK";
}
}
} catch(e){
// An error was received
throw new Exception("AJAX ERROR");
}
return responseBody;
}
Some other times, it works fine...
Am I doing anything wrong with this code?
Many thanks for your help.
EDITED WITH SOLUTION:
Many thanks for your help. The simply fact of using utf8.encode(json.encode(data)) did not fully work. So, I turned to the http library and it now works like a charm. The code is even lighter!
Here is the new version of the code:
Future<Map> ajaxPut(String serviceName, Map data) async {
var responseBody = json.decode('{"data": "", "status": "NOK"}');
try {
var response = await http.put(mid.urlBase + '/$_serverApi$serviceName',
body: json.encode(data),
headers: {
'X-mobile-uuid': await _getDeviceIdentity(),
'X-mobile-token': await mid.getMobileToken(),
'Content-Type': 'application/json; charset=utf-8'
});
if (response.statusCode == 200) {
responseBody = json.decode(response.body);
//
// If we receive a new token, let's save it
//
if (responseBody["status"] == "TOKEN") {
await mid.setMobileToken(responseBody["data"]);
// Let's change the status to "OK", to make it easier to handle
responseBody["status"] = "OK";
}
}
} catch (e) {
// An error was received
throw new Exception("AJAX ERROR");
}
return responseBody;
}
I got it working with
req.headers.contentLength = utf8.encode(body).length;
From an indirect tip of the Utf8Codec documentation which states
decode(List codeUnits, { bool allowMalformed }) → String
Decodes the UTF-8 codeUnits (a list of unsigned 8-bit integers) to the corresponding string.
That means thatutf8.encode() returns codeUnits which actually means List<uint8>.
Encoding a String payload would in theory return a list which length is the length of the payload in bytes.
So using httpClient means to always measure the length of the payload in bytes, not the length of a String which may differ.
Günter is right. Content-Length has to be the length of the byte array after encoding from a String to bytes in whatever encoding you server requires.
There's a package called http which provides a slightly higher level api (it uses dart.io httpClient under the hood) which takes care of encoding the post body and length for you. For example, when you need to send application/x-www-form-urlencoded form it will even take a Map and do all the encoding for you (you still need to encode to json yourself). It's equally happy to send just a String or List<int>. Here's an example:
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': json.encode({
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
}),
};
Response r = await post(
url,
body: body,
);
Seems your string contains multibyte characters.
UTF8-encode the string to get the correct length:
var body = utf8.encode(json.encode(data));