I am working on ionic project which needs to work offline. My issue is, how to save uploaded image offline in sqlite database, and when track any wifi connection, synch to online.
Image uploading online is working fine, using cordova camera plugin and filetransfer plugin.
You can use cordova file plugin's copyfile method to store the image locally, and then save its link in the database for further use. When the wifi is detected, just use that link to upload file to server with same cordovafile plugin.
$cordovaCamera.getPicture(options).then(function(sourcePath) { //for capturing image
console.log(sourcePath);
var sourceDirectory = sourcePath.substring(0, sourcePath.lastIndexOf('/') + 1); //image file with path url
var sourceFileName = sourcePath.substring(sourcePath.lastIndexOf('/') + 1, sourcePath.length); //image name
console.log("Copying from : " + sourceDirectory + sourceFileName);
console.log("Copying to : " + cordova.file.dataDirectory + sourceFileName);
//used to store file locally
$cordovaFile.copyFile(sourceDirectory, sourceFileName,
cordova.file.dataDirectory, sourceFileName).then(function(success) {
$scope.fileName = cordova.file.dataDirectory + sourceFileName;
console.log($scope.fileName, success);
$scope.propic = $scope.fileName;
}, function(error) {
console.log(error);
});
}, function(err) {
console.log(err);
});
Related
I have small problem while developing react, spring boot application dashboard.
Here is my problem, I developed file upload dashboard it's requests from client (react) to
backend server side (springboot) by axios call multipart-form.
Seem there is no problem on
uploading file to server (because uploaded file opens well inside of server and the file
size is equal).
However, when I downloading the file the file size increases and cannot
open properly (It's shows alarm that the file damaged).
Now I don't know where to find the solution :( plz help me.
here is my react code which has axios call with file name:
function fileDownlod(props) {
api.responseType = 'blob'
api.defaults.headers.common[`Authorization`] = 'Bearer ' + localStorage.getItem('token')
api
.post('/filedown', { uuid: props }, header)
.then((response) => {
const name = response.headers['content-disposition'].split('fileName=')[1]
console.log(response.headers)
console.log(name)
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', name)
link.style.cssText = 'display:none'
document.body.appendChild(link)
link.click()
link.remove()
})
and this is my spring boot code (where I checked that the file size both equal)
#CrossOrigin(value = {"*"})
#RequestMapping(value = "/filedown", method= {RequestMethod.POST, RequestMethod.GET})
public void fileDown (#RequestBody FileEntity param, HttpServletResponse response) throws Exception {
String fileFullPath = fileLocation + param.getUuid();
try{
Path filePath = Paths.get(fileFullPath);
FileEntity fileEntity = fileRepository.findByUuid(param.getUuid());
if(fileEntity.getContentType().contains("image")){
response.setContentType("multipart/form-data");
}else{
response.setContentType("application/octet-stream");
}
response.setHeader("Content-Disposition", "attachment; fileName=" + URLEncoder.encode(fileEntity.getFileName(),"UTF-8"));
response.setHeader("Content-Transfer-Encoding", "binary");
// response.setHeader( "Access-Control-Allow-Headers","Content-Disposition");
response.setHeader( "Access-Control-Expose-Headers","Content-Disposition");
byte[] fileByte = FileUtils.readFileToByteArray(new File(fileFullPath));
System.out.println("file size of fileByte: " + fileByte.length);
System.out.println("file size of file inf. from DB: " + fileEntity.getFileSize());
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
response.getOutputStream().close();
For more information, I'm develeping in macOS and when I deploy the application file download won't work in iphone eihter :( Any suggestion? thank you.
I found my answer by myself the problem was "api.responseType = 'blob'" which didn't work as responseType.
this was my solution below
api
.post('/filedown', { uuid: props }, { responseType: 'blob' }, header)
I need to download the pdf/word/excel file from external server in to my ionic application. Sample code below
const fileTransfer: FileTransferObject = this.transfer.create();
const url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
fileTransfer.download(url, this.file.dataDirectory + 'file.pdf').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
console.log("error : " +error);
});
I need to store all the files in my application itself not an external storage or an internal storage. Would this be possible?
By the way if we keep on store the files in the application itself then there is any application performance issue came?
Thanks
AK
I am using the ionic 2 framework and the cordova file plugin.
I am downloading a pdf file from a server, using the php readfile($path) method, on the client side, i am using Http from angular/http.
Now the problem is, that after the download and a save using the writeFile(path, file,data,options) method from ionic-native/file, the content of the file is not the same as the content from the server.
Notice: Left the output file and right the server version, both printed with the cat command.
I have no idea why the content is not the same.
The http call:
this.http.post(httpEndpoint + ":8280/download", data, headers).subscribe(response => {
me.proceedFile(response.text(), file, fileManager, opener);
});
Here the save:
private proceedFile(data:string, file:File, fileManager:FileManger,
opener:FileOpener) {
...
const me = this;
const putFile = function () {
fileManager.writeFile(fileManager.dataDirectory ,"data/" +
strid+"/" + file.name, data, true).then(_ => {
});
};
...
}
Regards Liz3
This question has been asked a fair bit before, but none of the solutions I've seen seem to work, potentially because of the way I stream the file back to the browser. The CSV I ultimately want is in a private S3 bucket and because of security middleware, I have to get it via a NodeJS endpoint. The code for the API is below.
exports.download = function(req, res) {
var recording = req.vsRecording,
s3 = new AWS.S3();
if(recording.data_uri){
try{
res.set('Content-Type', 'application/octet-stream');
var fileStream = s3.getObject({Bucket: 'processing-dispatched', Key: recording._id + '/aggregated.csv'}).createReadStream();
fileStream.pipe(res);
}
catch(err){
res.status(500).json({error: err});
}
}
else {
res.status(500).json({error: 'Recording does not have a report file.'});
}
};
This works perfectly and I can get the content of the file back to the browser. When it goes wrong is trying to get that content into be opened as a file download. Is there a special way to handle downloading streams?
The closest I've got is this code on the client, which sometimes seems to work on localhost if I turn my adblocker off - but does not work in production.
$scope.download = function(){
Report.download($state.params.recordingId).then(function(data){
var csvContent = "data:text/csv;charset=utf-8," + data.toString();
var encodedUri = encodeURI(csvContent);
window.open(encodedUri);
});
Report.download is just an angular service wrapper around my Node endpoint, it returns a promise and resolves the content of the file in the data variable.
reason might be the browser blocking the new window.
Allow all sites to show pop-ups in browser setting.
you can try thing in different ways create a file in node with fs and return url to the Front-end
or
you can Try the following code
$scope.download = function() {
Report.download($state.params.recordingId).then(function(data) {
var csvContent = "data:text/csv;charset=utf-8," + data.toString();
var a = document.createElement('a');
a.href = "data:application/csv;charset=utf-8," + csvContent;
a.setAttribute('download', "abc.csv");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
Here is the thing:-
I have over a thousand images saved locally in my mac. I have a landing page that mocks an ecommerce deal site. It would be tedious to have to manually type in the src url in the img tag for a thousand pictures. Thus, i thought i could somehow have this images dumped in a cloud storage or something and use REST api get method to extract these images in a response.data. Then assign it to a $scope variable and use ng-repeat to bind the images in my landing page view. Is this possible? If not, what are the alternatives? SQL database?
Appreciate your help. P.S. I am totally a beginner at web development.
Install node.js. It's Javascript for a server which should make it pretty easy since you already know Javascript.
On a Mac, you can install node like this:
brew install node
Use this node.js code (credit to codepedia.com, tweaked a little by me):
//include http, fs and url module
var http = require('http'),
fs = require('fs'),
path = require('path'),
url = require('url');
imageDir = './images/';
//create http server listening on port 3333
http.createServer(function (req, res) {
//use the url to parse the requested url and get the image name
var query = url.parse(req.url,true).query;
pic = query.image;
if (typeof pic === 'undefined') {
getImages(imageDir, function (err, files) {
var imageList = JSON.stringify(files);
res.writeHead(200, {'Content-type':'application/json'});
res.end(imageList);
});
} else {
//read the image using fs and send the image content back in the response
fs.readFile(imageDir + pic, function (err, content) {
if (err) {
res.writeHead(400, {'Content-type':'text/html'})
console.log(err);
res.end("No such image");
} else {
//specify the content type in the response will be an image
res.writeHead(200,{'Content-type':'image/jpg'});
res.end(content, "binary");
}
});
}
}).listen(3333);
console.log("Server running at http://localhost:3333/");
//get the list of jpg files in the image dir
function getImages(imageDir, callback) {
var fileType = '.jpg',
files = [], i;
fs.readdir(imageDir, function (err, list) {
for(i=0; i<list.length; i++) {
if(path.extname(list[i]) === fileType) {
files.push(list[i]); //store the file name into the array files
}
}
callback(err, files);
});
}
Run this from the command line to start you new image server (assuming you named the file "server.js"):
node server.js
You should see this text appear on the command line:
Server running at http://localhost:3333/
You can quickly test it by going to this address in your browser and you should see a JSON object showing you an array of all the filenames in the "./images" directory. By the way, this program assumes you're putting the images folder in the same directory as "server.js". You can put the images directory anywhere and just change the path of the variable "imageDir".
Now you can load the list of files from Angular using this code in your controller:
$http.get("http://localhost:3333", function(data) {
$scope.images = data;
});
In your view, you can now use an ng-repeat like this to display all the images:
<div ng-repeat="image in images" style="padding: 8px">
<img src="http://localhost:3333/image={{ image }}">
</div>
Note: this will work if you run it locally on your Mac or if you upload all the images to a server on which you can use Node.js.