send image and text at the same time flutter - flutter

I want to upload image and other types of data like string and integer with the HTTP post method at the same time. but i got error code said that json cant encode image file, i have this code on flutter :
static Future<ApiReturnValue<Asset>> addAsset(Asset asset, File imageFile,
{http.Client client}) async {
client ??= http.Client();
String url = baseUrl + 'asset';
var uri = Uri.parse(url);
var response = await client.post(
uri,
headers: {
"Content-type": "application/json",
"Authorization": "Bearer ${User.token}"
},
body: jsonEncode(
<String, dynamic>{
"name": asset.name,
"condition": asset.condition,
"purchase_date": asset.purchaseDate,
"price": asset.price,
"location": asset.location,
"description": asset.description,
"image": imageFile,
},
),
);
if (response.statusCode != 200) {
return ApiReturnValue(message: "Add item failed, please try again");
}
var data = jsonDecode(response.body);
Asset value = Asset.fromJson(data['data']['asset']);
return ApiReturnValue(value: value);
}
is that any way that I can send image and text on HTTP post request at the same time without separating the image using multipart request?

To include an image in the request body for POST, normally you have to convert it into a multipart file, then include it in the body as formdata. This required the server to expect the multipart file within the formdata itself when receive the image from client.
I'd like to recommend this package name dio for you. It supports MultipartFile, FormData and other powerful helper classes.
Here's an example:
static Future<bool> sendImage(String imagePath) async {
try {
final content = MultipartFile.fromFile(imagePath);
final contentType = 'multipart/form-data';
final Response response = await dio.post('$BASE_URL/$images',
data: FormData.fromMap({'file': content}),
options: Options(contentType: contentType));
if (response.statusCode == 200) {
return true;
}
return false;
} catch (error) {
return null;
}
}
You can read more on the FormData here

You can have your asset data in the request header:
var response = await client.post(
uri,
headers: {
"Content-type": "application/json",
"Authorization": "Bearer ${User.token}",
"asset-data": jsonEncode(
<String, dynamic>{
"name": asset.name,
"condition": asset.condition,
"purchase_date": asset.purchaseDate,
"price": asset.price,
"location": asset.location,
"description": asset.description
},
),
},
body: imageFile.readAsBytesSync(),
);
This will need you to modify your server-side code to read from the header.

Related

Patch method using dio with xxx-www-form-urlencoded produces internal server error

So, i have been trying to update user data using the patch method. The data should be of
xxx-www-form-urlencoded
Also there are two additional headers required by laravel :
Accept : application/vnd.api+json,
Content-Type : application/vnd.api+json
But when i try to use the patch method in dio it produces 500 status code error.
This is the code for the patch request :
Future<CustomerResponse> editCustomer(
String id, AddCustomerModel addCustomerModel) async {
print(addCustomerModel.toMap());
var box = await Hive.openBox("tokenBox");
String token = box.get("token");
FormData formData = FormData.fromMap({
"name": addCustomerModel.name,
"consumerType": addCustomerModel.consumerType,
"corporateType": addCustomerModel.corporateType ?? "",
"amc": addCustomerModel.amc,
"amcDate": addCustomerModel.amcDate ?? "",
"address": addCustomerModel.address,
"phoneNo[]": addCustomerModel.phoneNo,
});
try {
Response response = await dio.patch(
"${Config.baseUrl}${Config.appFunctionRoute}/id",
data: formData,
options:
Options(contentType: Headers.formUrlEncodedContentType, headers: {
"Authorization": "Bearer $token",
"Accept": "application/vnd.api+json",
"Content-Type": "application/vnd.api+json"
}));
if (response.statusCode == 200) {
return CustomerResponse.fromJson(response.data);
}
} catch (e) {
print(e);
}
return CustomerResponse();
}
So , should i change something in the server side or there is something wrong from my end.

Make a post HTTP

I follow the below code, but it seems not to work:
var body = jsonEncode(<String, String>{
'uid': uid,
'limit': '10',
'offset': '2',
'action': 'feed',
});
final response = await http.post(
Uri.parse('http://abc.or/fb/selectPosts.php'),
body: body,
);
if (response.statusCode == 200) {
List<Post> posts = [];
// If the server did return a 200 OK response,
// then parse the JSON.
print((jsonDecode(response.body)));
return List<Post>.from(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to update album.');
}
My API looks like this: http:/abc.or/fb/post.php?uid=aaaa&limit=10&offset=2&action=feed
try this.
import 'package:http/http.dart';
...
static const urlPrefix = 'https://jsonplaceholder.typicode.com';
...
Future<void> makePostRequest() async {
final url = Uri.parse('$urlPrefix/posts');
final headers = {"Content-type": "application/json"};
final json = '{"title": "Hello", "body": "body text", "userId": 1}';
final response = await post(url, headers: headers, body: json);
print('Status code: ${response.statusCode}');
print('Body: ${response.body}');
}
Those are query fields not request body fields.
They are passed in the link or as queryparematers in a Uri
final response = await http.get(
Uri(
path: <your url without the queries(http://abc)>,
query: <Your queries as they are in the string (uid=aaaa&limit=10&offset=2&action=feed), you can use string interpolation to fix the values in or better still use queryparematers, not both>
queryParameters : <String, dynamic>{ 'uid': uid, 'limit': 10, 'offset': 2, 'action': feed },)
);
I use a get method which should be the standard for such url. Do confirm from whoever wrote the api if it is a uses a get or post method.

Cannot upload image using dio post request

I am trying to upload a photo with caption to REST API. But since it is my first time, I am getting some exceptions. My code for uploading the image is shown below:
Dio dio = new Dio();
dio.options.headers['content-Type'] = 'multipart/form-data';
dio.options.headers['Authorization'] = 'Token ${box.get('token')}';
FormData formData = FormData.fromMap({
"author": box.get('user_id'),
"description": _caption,
"image": MultipartFile.fromFileSync(_image.path,
filename: _image.path.split(Platform.pathSeparator).last)
});
dio
.post("$baseURL/posts/create/",
data: formData,
options:
Options(method: 'POST', responseType: ResponseType.plain))
.then((response) => print(response))
.catchError((error) => print(error));
After I run this on my device and try to upload image, it directs me to dio.dart package line throw assureDioError(e, options);
If you have any knowledge with uploading images using dio, kindly help solve it.
UPDATED: body of json
{
"author": null,
"description": "",
"image": null
}
UPDATED: I tried with another service uploading image (not dio)
// string to uri
var uri = Uri.parse("$baseURL/posts/create/");
// create multipart request
var request = http.MultipartRequest("POST", uri);
// add headers with Auth token
Map<String, String> headers = {
"Authorization": "Token ${box.get('token')}",
"Content-type": "multipart/form-data"
};
request.headers.addAll(headers);
// add fields
Map<String, String> fields = {
'author': box.get('user_id').toString(),
'description': _caption,
};
request.fields.addAll(fields);
// multipart that takes file
var multipartFile = http.MultipartFile(
'file',
_image.readAsBytes().asStream(),
_image.lengthSync(),
filename: _image.path.split('/').last,
contentType: MediaType('image', 'jpeg'),
);
// add file to multipart
request.files.add(multipartFile);
print(request.toString());
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
I have tried uploading images with the above code as well. But this returns me the error saying "image":["No file was submitted."]

I would like to upload a image and profile data in Multipart/Formdata format in flutter when hit a api i got response failed

Here is my post api code i try to upload file (image from image picker)and profilePojo(data like username ,fname, lastname etc.) when i run code i got result failed .
'''
void addData(final profilePojo) async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String token = preferences.getString('token');
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"profilePojo":profilePojo,//profilePojo means i pass heaar string of data on button click
});
String url =pass here url
http
.post(
url,
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token',
// "Content-Type":"multipart/form-data",
"accept": "application/json",
},
body: formData.toString()
)
.then((response) {
if (response.statusCode == 200) {
var myData = json.decode(response.body);
if(myData['result']=="success"){
setState(() {
print(myData);//print response success
_showDialog();
getData();
});}
else{
print(response.statusCode);
print(myData);
}
} else {
print(response.statusCode);
print("object");
}
});
}
'''
I'm currently using dio for this kind of requests, here is my example:
final futureUploadList = imageList.map((img) async {
print(img.path);
return MultipartFile.fromFile(img.path);
});
final uploadList = await Future.wait(futureUploadList);
FormData data = FormData.fromMap({
"images": uploadList
});
dio.post('/images',
data: data, options: Options(headers: {'Authorization': 'Bearer abcd'}));

How to format body for form-data header

This might be probably already answered question but I can not find one. How do we format data body for form-data http response? I tried to encode it to json but that didn't work with error
Unhandled Exception: Multipart: Boundary not found
Future<void> createProfile() async {
final body = {
"firstName": "first",
"lastName": "last",
"image": "path-to-image"
};
try {
final http.Response response = await http.post(APIPath.createProfile(),
headers: {"Authorization": "Bearer $token","Content-Type": "multipart/form-data"},
body: json.encode(body)); //<-- this doesn't work
final jsonResponse = json.decode(response.body);
if (response.statusCode != 201) {
throw HttpException(jsonResponse["error"]);
}
} catch (error) {
throw error;
}
}
Flutter Documentation
var uri = Uri.parse('https://example.com/create');
var request = http.MultipartRequest('POST', uri)
..headers['authorization'] = 'auth header value'
..fields['user'] = 'nweiz#google.com'
..files.add(await http.MultipartFile.fromPath(
'package', 'build/image.png',
contentType: MediaType('image', '*')));
var response = await request.send();
if (response.statusCode == 200) print('Uploaded!');