flutter send empty file to server - api

Hi i'm trying to upload a file to a server via a flutter app but the file is always empty.
it was working fine and after that it stopped working.
here is my code :
static uploadImageToServer(String image) async {
File imageFile = new File(image);
Map<String, String> headers = {
'Content-Type': 'multipart/form-data',
'Accept-Charset': 'UTF-8'
};
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
print(imageFile.path);
var uri = Uri.parse("http://planning.test/test_image");
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('File', stream, length,
filename: "test_image_failure.jpg");
request.headers.addAll(headers);
request.fields['Destination'] = '/';
print("**********");
print(multipartFile.filename);
print(uri);
print(multipartFile.length);
print("**********");
request.files.add(multipartFile);
print(request.contentLength);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
and with dio package
_dioUpload(String imageFile)async {
var dio = Dio();
var formData = FormData();
formData.files.add(MapEntry(
"File",
await MultipartFile.fromFile(imageFile, filename: "xx.png"),
));
print(formData.files.first.value.length);
var response = await dio.post(
"http://planning.test/test_image",
data: formData,
onSendProgress: (received, total) {
if (total != -1) {
print((received / total * 100).toStringAsFixed(0) + "%");
}
},
);
print(response);
}
i don't understand what is happening everything look fine and the file exist.
thx

I'm using the retrofit for flutter and to send an empty file I got it as follows.
File.fromRawPath(Uint8List.fromList([0]))
Retrofit example
#PUT('profile')
#FormUrlEncoded()
Future<void> update(#Header("Authorization") String token,
#Field() String name, #Field() String surname, #Part() File avatar);
Example
await myapi.update("_token_","Sr", "Burton", File.fromRawPath(Uint8List.fromList([0])));

Related

Couldn't upload image to server in Flutter Web

I've created a flutter application for android and web. In Flutter web, I tried to upload image to server just like it works with firebase. But it is not working somehow. I've seen some solutions for this task. But I wonder, what is actually wrong with my code.
final url = Uri.parse('$apiHeader/poststore');
String token = await getUserToken();
Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
var request = http.MultipartRequest("POST", url);
request.headers.addAll(headers);
request.fields['category_id'] = model.categoryId;
request.fields['title'] = model.title;
//I want to know about this section of the code, how can i make it work
if (kIsWeb) {
final fileBytes =
await model.image.readAsBytes(); // convert into bytes
var multipartFile = http.MultipartFile.fromBytes(
'fileName[]', fileBytes); // add bytes to multipart
request.files.add(multipartFile);
} else {
var multipartFile = await http.MultipartFile.fromPath(
'fileName[]', model.image.path);
request.files.add(multipartFile);
}
var response = await request.send();

Flutter : Multipart File request not working

I want to upload image by multipart File request. With using this code When I pass two image files then it's working fine. But when I want to pass one image file and another is null then it's not working.
where is the problem? How can I solve this ?
Here is my code -
Future<Map<String, dynamic>> updateprofile(
UpdateProfileInfo updateProfileInfo,
File imageFile,
File signatureFile) async {
String url = "$baseAPIUrl/update-profile-info";
String _token = await SavedData().loadToken();
String authorization = "Bearer $_token";
final headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
"Authorization": authorization
};
var request = http.MultipartRequest("POST", Uri.parse(url));
request.headers.addAll(headers);
request.fields.addAll(updateProfileInfo.toJson());
request.files
.add(await http.MultipartFile.fromPath('image', imageFile.path));
request.files.add(
await http.MultipartFile.fromPath('signature', signatureFile.path));
print(" Update Profile Json ${updateProfileInfo.toJson()}");
print("Request Fields ${request.fields}");
http.StreamedResponse response = await request.send();
String respStr = await response.stream.bytesToString();
dynamic respJson;
try {
respJson = jsonDecode(respStr);
} on FormatException catch (e) {
print(e.toString());
}
print('API ${response.statusCode}\n $respJson');
bool isSuccess = response.statusCode == 200;
var data = json.decode(respStr);
return {
'isSuccess': isSuccess,
"message": isSuccess ? data["success"]["message"] : null,
"name": isSuccess ? data["success"]["name"] : null,
"classgroup": isSuccess ? data["success"]["classgroup"] : null,
"image": isSuccess ? data["success"]["image"] : null,
"error": isSuccess ? null : data['error']['message'],
};
}
Here is postman Screenshot
1.
2. POSTMAN Generated code for Dart - http
when one of your file is null, you should avoid adding it to the request body.
if(imageFile != null){
request.files
.add(await http.MultipartFile.fromPath('image', imageFile.path));
}
if(signatureFile != null){
request.files.add(
await http.MultipartFile.fromPath('signature', signatureFile.path));
}
its because signatureFile.path is going to cause an error here
using dio package should work
Future<bool> updateImage(var pickedFile) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();` <br/>
var token = sharedPreferences.getString("token");
Dio dio = Dio();
final File file = File(pickedFile.path);
String fileName = file.path.split('/').last;
dio.options.headers["authorization"] = token;
FormData formData = FormData.fromMap({
"image": await MultipartFile.fromFile(file.path),
});
try {
var response = await dio.post(API.kBASE_URL, data: formData);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
} catch (r) {
return false;
}
}

Flutter: upload Image error via API function

I'm trying to upload images and some data via API from my app and I have no error in my console and I don't know what's wrong with my function.
This is the code which I use:
upload(File imageFile) async {
var user =
Provider.of<LoginUserProvider>(context, listen: false).userData.data;
DateFormat formater = DateFormat('yyyy-MM-dd');
String formatted = formater.format(dateTime);
var stream =
// ignore: deprecated_member_use
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var headers =
Provider.of<LoginUserProvider>(context, listen: false).httpHeader;
var uri = Uri.parse(
"xyz");
var request = new http.MultipartRequest("POST", uri);
request.headers.addAll(headers);
//request.headers.addAll(Environment.requestHeaderMedia);
var multipartFile = new http.MultipartFile(
'attachment',
stream,
length,
filename: imageFile.path,
contentType: MediaType('application', 'x-tar'),
);
request.fields['section_id'] = VillaID.toString();
request.fields['date'] = formatted;
request.fields['description'] = descriptionController.text;
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
try {
final streamedResponse = await request.send();
final response = await http.Response.fromStream(streamedResponse);
print(json.decode(response.body));
final responseData = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode == 200 || response.statusCode == 201) {
return true;
}catch (error) {
print(error);
return false;
}
return true;
}
So can anyone help me with my issue, please!
you are sending the same request twice
1st
var response = await request.send();
Second
final streamedResponse = await request.send();
before sending the same request, create them again.
regarding your code you don't need to create a response again. use the first one in the other places.

how to download a pdf file from an url in angular 5

I currently spend one day in this issue,still failed to download a file from an url in angular 5
leadGenSubmit() {
return this.http.get('http://kmmc.in/wp-content/uploads/2014/01/lesson2.pdf',
{responseType:ResponseContentType.Blob}).subscribe((data)=>{
console.log(data);
var blob = new Blob([data], {type: 'application/pdf'});
console.log(blob);
saveAs(blob, "testData.pdf");
},
err=>{
console.log(err);
}
)
}
when I run above code it shows following error
ERROR TypeError: req.responseType.toLowerCase is not a function
at Observable.eval [as _subscribe] (http.js:2187)
at Observable._trySubscribe (Observable.js:172)
how can I solve this issue.Can any one post the correct code to download a pdf file from an url in angular 5?
I think you should define header and responseType like this:
let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/pdf');
return this.http.get(url, { headers: headers, responseType: 'blob' });
Here is my simple solution to open a PDF based on an ID in Angular :
In my service, I created this method :
public findById(id?: string): Observable<Blob> {
return this.httpClient.get(`${this.basePath}/document/${id}`, {responseType: 'blob'});
}
Then in my component, I can do use this method (behind a button or whatever):
showDocument(documentId: string): void {
this.yourSuperService.findById(documentId)
.subscribe((blob: Blob): void => {
const file = new Blob([blob], {type: 'application/pdf'});
const fileURL = URL.createObjectURL(file);
window.open(fileURL, '_blank', 'width=1000, height=800');
});
}
Try this
let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/pdf');
return this.http.get(url, { headers: headers, responseType: 'blob' as 'json' });
References:
Discussion on Angular Github
Stackoverflow

How can using JS to print a Byte array to local machine printer?

i have pdf's content in byte Array. I want a client way to print this pdf to local printer using js.
It is possible?
$http({
url: yourUrl,
method: 'GET',
headers: {
'Content-type': 'application/pdf'
},
responseType: 'arraybuffer'
}).success(function (data, status, headers, config) {
var pdfFile = new Blob([data], {
type: 'application/pdf'
});
var pdfUrl = URL.createObjectURL(pdfFile);
var printwWindow = $window.open(pdfUrl);
printwWindow.print();
}).error(function (data, status, headers, config) {
alert('Sorry, something went wrong')
});
You need to open it in Browser window by a Blob first and call print function
i have not tested this code but hopfully it will work
var byteArray = yourDocumentBytes;
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
// This will check if the browser is IE
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))
{
var blob = new Blob(byteArray, { type: 'application/pdf' });
window.navigator.msSaveBlob(blob, documentName);
} else // If another browser
{
var element = document.createElement('a');
element.setAttribute('href', 'data:application/pdf;base64,' + encodeURIComponent(getBase64(byteArray)));
element.setAttribute('download', documentName);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// and call print function like this
window.print()