Http listening to upload progress Flutter Web - flutter

I was trying to listen to the upload progress using StreamedRequest and wanted to show the upload progress in UI by listening to bytes sent, but for some reason, it doesn't seem to work. The file is being picked with the file picker package and the selected file is in binary format (Unit8List). Here's the code:
final sha1OfFileData = sha1.convert(fileData);
try {
final request = http.StreamedRequest('POST', Uri.parse(data['uploadUrl']));
request.headers.addAll({
'Authorization': data['authorizationToken'],
'Content-Type': "application/octet-stream",
'X-Bz-File-Name': fileName,
'X-Bz-Content-Sha1': sha1OfFileData.toString(),
'X-Bz-Server-Side-Encryption': 'AES256',
});
request.sink.add(fileData);
final streamedResponse = await request.send();
var received = 0;
var total = streamedResponse.contentLength ?? -1;
streamedResponse.stream.listen(
(List<int> chunk) {
received += chunk.length;
if (total == -1) {
print('Received $received bytes');
} else {
final progress = received / total;
print('Upload progress: ${(progress * 100).toStringAsFixed(2)}%');
}
},
onDone: () async {
final responseBytes = await streamedResponse.stream.toBytes();
final responseString = utf8.decode(responseBytes);
response = jsonDecode(responseString);
print(response);
},
onError: (error) {
print('Error uploading file: $error');
},
cancelOnError: true,
);
} catch (e) {
print(e);
}
However if I upload it with the normal request, it works, here's that code:
final sha1OfFileData = sha1.convert(fileData);
var response;
try {
final request = http.Request('POST', Uri.parse(data['uploadUrl']));
request.headers.addAll({
'Authorization': data['authorizationToken'],
'Content-Type': "application/octet-stream",
'X-Bz-File-Name': fileName,
'X-Bz-Content-Sha1': sha1OfFileData.toString(),
'X-Bz-Server-Side-Encryption': 'AES256',
});
request.bodyBytes = fileData;
final streamedResponse = await request.send();
final responseBytes = await streamedResponse.stream.toBytes();
final responseString = utf8.decode(responseBytes);
response = jsonDecode(responseString);
print(response);
} catch (e) {
print(e);
}

Related

Retrieving data from http web call in flutter into a list object always empty

List is always empty even though body has contents. I am new to flutter so bare with me if this is basic. I am wanting to get back a list of station data I am coming from a c# background so forgive me if am missing something simple the test string body has the items and can see the items when i debug
class HttpService {
final String url = "url hidden";
final String host = 'url hidden';
final String apiSegment = "api/";
// ignore: non_constant_identifier_names
void login(email, password) async {
try {
Map<String, String> body = {
'username': email,
'password': password,
};
Map<String, String> headers = {'Content-Type': 'application/json'};
final msg = jsonEncode(body);
Response response =
await post(Uri.parse("$url/Login"), headers: headers, body: msg);
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data['jwtToken']);
print('Login successfully');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('jwtToken', data['jwtToken']);
List<Stations> stationData = await getStationData('11');
var test = stationData;
} else {
print('failed');
}
} catch (e) {
print(e.toString());
}
}
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
List<Stations> stationData = <Stations>[];
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
var body2 = body.toString();
stationData = body
.map(
(dynamic item) => Stations.fromJson(item),
)
.toList();
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
print(e.toString());
}
return stationData;
}
}
I am calling my function from the same class
List<Stations> stationData = await getStationData('11');
Data from body
Actually the problem is you are returning the data after the end of try catch.
Try this
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
final stationData = List<Stations>.from(body.map((item) => Stations.fromJson(item))); // made some changes
return stationData;
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
rethrow;
}
}
I hope this will help you

Flutter: How to send multiple images using for loop

I am using http package to perform multipart request.I am trying to upload multiple images using for loop but I am not getting any idea how to do it following is my postman response in the below image you can see 2 fields one is attribute and another one is image here I want to loop only adhar and pan inside attributes after sending "mobileno":"4567654","role":"p","userstatus":"D", to database
following is my multipart request code
Future<void> insertCategory(String category, BuildContext context) async {
var flutterFunctions =
Provider.of<FlutterFunctions>(context, listen: false);
var data = {"mobileno":"4567654","role":"p","userstatus":"D","adhar":"adhar","pan":"pan"};
var url = PurohitApi().baseUrl + PurohitApi().insertcategory;
Map<String, String> obj = {"attributes": json.encode(data).toString()};
try {
loading();
final client = RetryClient(
http.Client(),
retries: 4,
when: (reponse) {
return reponse.statusCode == 401 ? true : false;
},
onRetry: (request, response, retryCount) async {
if (retryCount == 0 && response?.statusCode == 401) {
var accesstoken = await Provider.of<Auth>(context, listen: false)
.restoreAccessToken();
request.headers['Authorization'] = accesstoken;
print(accesstoken);
}
},
);
var response = await http.MultipartRequest('Post', Uri.parse(url))
..files.add(await http.MultipartFile.fromPath(
"imagefile", flutterFunctions.imageFile!.path,
contentType: MediaType("image", "jpg")))
..headers['Authorization'] = token!
..fields.addAll(obj);
final send = await client.send(response);
final res = await http.Response.fromStream(send);
var messages = json.decode(res.body);
loading();
print(messages);
} catch (e) {
print(e);
}
}
Future<Object> addUserImages(List<XFile> files, String userID, String token) async {
try {
var url = Uri.parse(API_BASE_URL + addUserImagesUrl);
var request = http.MultipartRequest("POST", url);
request.headers['Authorization'] = "Bearer ${StaticServices.userBaseModel!.token!.token}";
for (var i = 0; i < files.length; i++) {
String fileName = DateTime.now().microsecondsSinceEpoch.toString().characters.takeLast(7).toString();
var pic = http.MultipartFile.fromBytes("files", await File(files[i].path).readAsBytes(), filename: '${userID}_${i}_$fileName', contentType: MediaType("image", files[i].mimeType ?? "png"));
//add multipart to request
request.files.add(pic);
}
var response = await request.send();
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
if (response.statusCode == 200) {
return Success(response: Images.fromJson(jsonDecode(responseString)));
}
return Failure(
errorMessage: responseString,
);
} on HttpException {
return Failure(errorMessage: "No Internet Connection");
} on FormatException {
return Failure(errorMessage: "Invalid Format");
} on SocketException {
return Failure(errorMessage: "No Internet Connection");
} catch (e) {
return Failure(errorMessage: "Invalid Error");
}
}

cannot able to send files with extact format in flutter

I'm currently working in a flutter, I'm trying to send a file to the backend server. But I can send a file but the extension is showing as BIN and the file is not supported.
pick() async {
var img = await ImagePicker().getImage(source: ImageSource.gallery);
image = img;
}
send() async {
// if (imageFile == null) {
// return Get.snackbar("alert", 'Please select image');
// }
try {
String? message = messageController.text;
final url = Uri.parse('http://localhost:8000/integration-test');
//Map<String, String> headers = {'Authorization': 'Bearer $token'};
Uint8List data = await this.image.readAsBytes();
List<int> list = data.cast();
var request = http.MultipartRequest('POST', url)
//..headers.addAll(headers)
..fields['sender'] = "venkat"
..fields['numbers'] = numbers
..fields['message'] = message;
if (image != null) {
request.files.add(http.MultipartFile.fromBytes('file', list,
filename: 'example.jpeg'));
}
var response = await request.send();
//var decoded = await response.stream.bytesToString().then(json.decode);
if (response.statusCode == 200) {
Get.snackbar("alert", 'SUCESS');
} else {
Get.snackbar("alert", 'FAILED');
}
} catch (e) {
Get.snackbar('alert', 'Image failed: $e');
}
}
and help to set the file name dynamically.
when i done it with ajax and jquery it works file i need the exact result like this
let formData = new FormData();
let file = $('#1file')[0].files[0];
const sender=c;
const message = $('.i-message').val();
const datepick=$("#i-datetimepicker").val();
formData.append('sender',c);
formData.append('numbers',JSON.stringify(irecepient));
formData.append('message',message);
if(file){
formData.append('file',file);
}
if(datepick){
formData.append('date',datepick);
}
$.ajax({
type: "POST",
url: "http://localhost:8000/integration-test",
//enctype: 'multipart/form-data',
contentType:false,
processData:false,
data: formData,
success: function (data) {
if(data !=0){
$('.logs').append($('<li>').text("task processing"));
}else{
$('.logs').append($('<li>').text("task failed"));
}
}
});
});
this works good and i expect the above flutter code to do this

how to show a pdf fetched from an API response in flutter?

I am working in a project where I have to show certificate that the user finished a course, there is an URL of the API that uses the get method within a token to have acces to a pdf file, the problem is that I do not know how to show or transform that response into a pdf, using flutter,
I tried to use the url_launcher dependency because in the browser shows the pdf normally, but the problem is that it I need to pass a token to that url.
the second thing that i tried was to fetched the response of the api and save it in a temporal file and use flutter_pdfview dependency but it shows errors.
this is how the response of the api looks like:
%PDF-1.4
1 0 obj
<<
/Title (þÿ)
/Creator (þÿ)
/Producer (þÿQt 5.5.1)
/CreationDate (D:20211120205047)
>>
endobj
2 0 obj
<<
/Type /Catalog
/Pages 3 0 R
>>
endobj
4 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
this is what I tried:
Future LoadPDF(APIurl)async {
Map<String,String> Headers={
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': 'Bearer $userToken'
};
final response = await http.get(Uri.parse(APIurl),headers: Headers);
final bytes = response.bodyBytes;
// print(response.bodyBytes);
var dir = await getTemporaryDirectory();
File file = File(dir.path + "/data.pdf");
await file.writeAsBytes(bytes, flush: true);
setState(() {
loadDocument(file);
});
// return file;
}
Here is how I solved it:
Future<http.Response> apiCall(String fileId, String clientId) async {
String token = (await _storage.read(key: 'token')).toString();
final url = Uri.parse('$BASE_URL/oauth/notes/upload/view/$fileId/$clientId');
final headers = {"Authorization" : "Bearer $token", "Accept" : "*/*", "Accept-Encoding" : "gzip, deflate, br", "Connection": "keep-alive"};
final response = await http.get(url, headers: headers);
return response;
}
Future<File?> getContent(String fileId, String clientId, String extension) async {
//this is the api mentioned in next part
http.Response res = await api.apiCall(fileId, clientId);
dynamic response = res.bodyBytes;
if (response != null) {
final Directory? appDir = Platform.isAndroid
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
String tempPath = appDir!.path;
final String fileName =
DateTime.now().microsecondsSinceEpoch.toString() + extension;
File file = File('$tempPath/$fileName');
if (!await file.exists()) {
await file.create();
}
await file.writeAsBytes(response);
return file;
}
}
File? file = await contentService.getContent(
fileid,
id,
'.pdf');
if (file != null) {
final String? result = await openFile(file.path.toString());
if (result != null) {
print('result');
print(result);
// Warning
}
}
static Future<String?> openFile(String url) async {
final OpenResult result = await OpenFile.open(url);
}
Hi I got the same response as you. Here I used Dio api structure. Take this as reference. Below code work fine for me.
Future<File?> downloadPDF(String applicantId, String templateId) async {
try {
final response = await dioClient.post('xxxxxx/pdfService/pdfOperation/downloadPDF', data:DownloadRequestDTO(applicantId, templateId), headers: <String, dynamic>{
'Content-Type': 'application/json'}, options: Options(responseType: ResponseType.bytes));
if (response != null) {
final Directory? appDir = Platform.isAndroid
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
String tempPath = appDir!.path;
final String fileName =
DateTime.now().microsecondsSinceEpoch.toString() + '-' + 'akt.pdf';
File file = new File('$tempPath/$fileName');
if (!await file.exists()) {
await file.create();
}
await file.writeAsBytes(response);
return file;
}
throw DownloadException('The download failed.', response);
} catch (value) {
if (value is DioError) {
print(value.response);
}
print(value.toString());
}
}
Then use open_file package to open downloaded file
static Future<String?> openFile(String url) async {
final OpenResult result = await OpenFile.open(url);
switch (result.type) {
case ResultType.error:
return result.message;
case ResultType.fileNotFound:
return LocaleKeys.fileNotFound.tr();
case ResultType.noAppToOpen:
return LocaleKeys.noAppToOpen.tr();
case ResultType.permissionDenied:
return LocaleKeys.permissionDenied.tr();
default:
return null;
}}
And call this functions as below
Future<void> downloadAndOpenFile(BuildContext context) async {
try {
File? file = await downloadPDF('1234', 'xxxxxx');
if (file != null) {
final String? result = await openFile(file.path.toString());
if (result != null) {
// Warning
}
}
} catch (e) {
print(e);
}}
you can use flutter_pdfview package to show pdf:
loadDocument(file) {
PDFView(
filePath: file.path,
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: false,
onRender: (_pages) {
setState(() {
pages = _pages;
isReady = true;
});
},
onError: (error) {
print(error.toString());
},
onPageError: (page, error) {
print('$page: ${error.toString()}');
},
onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController);
},
onPageChanged: (int page, int total) {
print('page change: $page/$total');
},
),
}

http MultipartRequest file not receiving in server

I'm trying to upload image to my server but it's not receiving in my server when I upload file from app. But if I upload via postman it works but not from simulator
My Code
final request = http.MultipartRequest(
'POST', Uri.parse(''));
request.fields['title'] = title.text;
request.fields['sub_title'] = subTitle.text;
request.files
.add(await http.MultipartFile.fromPath('profile_photo', photo.path));
request.files
.add(await http.MultipartFile.fromPath('profile_video', video.path));
var response = await request.send();
var responseString = await response.stream.bytesToString();
print(responseString);
`
Output
{'title': 'zia', 'sub_title' : 'sultan', 'profile_photo' : {}, 'profile_video' : {}}
I too faced a similar issue and here is the solution to how I fixed it:
var fileExtension = AppUtils.getFileExtension(filePath);
if (fileExtension.isEmpty) {
AppUtils.showToast('File extension was not found');
return false;
}
final file = await http.MultipartFile.fromPath('vid', filePath,
contentType: MediaType('application', fileExtension));
request.files.add(file);
var res = await request.send();
if (res.statusCode == 200) {
final respString = await res.stream.bytesToString();
debugPrint('respString: $respString');
}
AppUtils:
class AppUtils {
static String getFileExtension(String filePath) {
try {
int index = filePath.lastIndexOf('.');
return filePath.substring(index + 1);
} catch (e) {
return '';
}
}
}