So i am handling a multiple file upload on my client side, where my html looks like the following
form(method='post', enctype='multipart/form-data')#createReportForm
input(type='file', multiple='multiple', accept='image/png, image/gif, image/jpeg, image/jpg', name='uploadImages', data-max-size='5000000')#uploadFile
Now on my server side to access the contents of the file and other info i am using
req.files.uploadImages. This works fine if one file attached, but when multiple files are attached on the client this object only reads the last attached file and not the first one
Whats the reasoning behind this? Shouldn't req.files.uploadImages have info about both the files?
If multiple files are selected the req.files.uploadImages would hold all the files.
You can just loop over them:
var files = [].concat(req.files.uploadImages);
for(var x = 0; x < files.length; x++){
// upload file
}
Related
I am using Vue.js in a current project of mine and in that I need a feature, which will help any user to download pics that are available in the gallery.
There is an option that the user can select multiple images by clicking on the checkbox besides every image and to download the user needs to click a button to download all the pics that the user may have selected. The download will compress all the selected images to a zip folder and then the downloading stars and the user gets a final zip folder of all of the images that were selected.
To deliver this feature I have tried many Vue.js libraries but only JSZip was able to work for some extend. JSZip packed the images to a .zip and then downloads the zip folder but the images that are being packed, the type:"image/?" is also present but when one will open the file to see the image , then it gives an error of:
not an image of the defined type
in the image viewer. Here is the sample of the code that I have used:
export default {
methods: {
download_btn() {
var zip = new JSZip()
var img = zip.folder("images")
for (i = 0; i < this.image.length; i++) {
img.file("img.png", this.image[i].imageurl)
}
zip.generateAsync({
type: "blob"
}).then(function(content) {
saveAs(content, "img_archive.zip")
})
}
}
}
This code only saves one picture in the zip folder and also you can't open the image file.
Have a look at this one. Maybe it will help.
https://jsfiddle.net/jaitsujin/zrdgsjht/
You can manage zip folder structure by modifying this line
filename = filename.replace(/[\/\*\|\:\<\>\?\"\\]/gi, '').replace("httpsi.imgur.com","");
According to https://stuk.github.io/jszip/documentation/api_jszip/file_data.html the file method expects the image data as the second param to the call. It looks like you are passing the url of the image instead of the actual image bytes. If you refer to the docs you will see they retrieve the image via an ajax call.
To save more than one image, try using the number in the filename. And you'll have to use the image data, not the url, just like Deadron said.
In the docs they use xhr within a promise, see https://stuk.github.io/jszip/documentation/examples/downloader.html
Instead of:
for (i = 0; i < this.image.length; i++) {
img.file("img.png", this.image[i].imageurl)
}
Try:
for (i = 0; i < this.image.length; i++) {
img.file("img" + i + ".png", /* image data */)
}
I have a scenario in my test suite, where I need to
Click on a button.
Upload an image from a specified directory.
Wait for 15 seconds
Repeat Steps 1-3 for all the images in the specified directory.
How can I achieve this - uploading an array of images, or a group of images, in specified folder, one by one. The test also includes the check that an image should not have been uploaded before.
I am able to upload a single file using the code below -
var fileUpload = 'path_to_file';
absolutePath = path.resolve(__dirname,fileUpload);
console.log(absolutePath);
this.file_Upload2.sendKeys(absolutePath);
browser.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(20000);
Please note that there is only a single button for uploading the images and it remains constant.
If you change your fileUpload variable to point to the directory where the files are held, rather than the file itself, you can just loop over everything in the directory. Something like this:
var fileUpload = 'path_to_directory';
var file_Upload2 = this.file_Upload2;
var absolutePath = path.resolve(__dirname, fileUpload);
fs.readdir(absolutePath, (err, files) => {
for (i = 0; i < files.length; i++) {
var fullPath = path.resolve(absolutePath, files[i]);
file_Upload2.clear().sendKeys(fullPath);
browser.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(20000);
}
});
I would like to allow a user to upload multiple files through Ajax. If some of the files are too large I would like to remove them from the upload list. How can I go about doing this? I currently have the following for my input field.
<input id="file" type="file" onChange={this.handleChange.bind(this)} required multiple />
So far I have come up with something like this to verify which files are too large:
handleChange(event) {
const target = event.target;
if (target.type === 'file'){
console.log("FILES")
const files = target.files
console.log("The following files are too large")
for (let i=0; i < files.length; i++){
if (files[i].size > 50000){
console.log(files[i].name)
}
}
}
}
The thing I am confused about is how files are handled, as they are not really links to the actual files on the file system. How does the file structure work? How can I store the good files into a new file structure that is uploadable with Ajax?
target.files is just an array. You can simple filter it, removing the files you don't want and do whatever you want with the new array (e.g. store it in the component's state).
const files = target.files.filter(file => file.size <= 50000);
this.setState({files});
// or uploadFiles(files)
If you are asking how to actually send files via an XMLHTTPRequest, this can be done with FormData:
const data = new FormData();
files.forEach(file => data.append(file.name, file));
and then send the FormData object via the XMLHTTPRequest.
I would like to be able to edit a file that has been selected for upload. I want to search and replace text in case absolute files should be made relative...
I notice in the File API I can do some of it, but I get a little stuck:
document.getElementById('exampleInputFile').onchange = function(event) {
var fileToLoad = event.target.files[0];
if (fileToLoad) {
var reader = new FileReader();
reader.onload = function(fileLoadedEvent) {
var textFromFileLoaded = fileLoadedEvent.target.result;
//Use logic to remove absolute files
//Upload S3
};
reader.readAsText(fileToLoad, 'UTF-8');
}
};
I am trying to figure out how now to convert that text to a proper File so that I can upload it to S3 using an existing api that expects something returned by: event.target.files[0] code above.
I do not want the server to handle any heavy lifting here if I can avoid it (files can easily be a few megabytes since they can be 3D models).
Assuming you know the url of the file when it lands in the S3 bucket, you can retrieve the file using a http.get, which will give you the contents of the (I assume plain text file). You can then parse that file and do whatever modification you need to do on the contents. If the file has changed, you can then write it back to the S3 bucket to replace the original file.
On AWS you can use Lambda to execute NodeJS code when an event is triggered (for example an upload to a specified bucket).
I need log file(s) from user so I can read and analyze those. For example somekind of drop area, where user drops a file, then I can read it with javascript?
I use Angular2 rc5. I have node.js running backside, but I don't need the data there. I need it only at client side.
Is it possible to read and parse file content with just frontend tech, like angular2 and javascript? Or do I have to upload the file to server and analyze it there?
It is possible!
I ended up doing it like this. This reads all the files that are selected with file dialog. I don't need to send these to node.js. I can just manipulate these on client.
<input type='file' accept='text/plain' multiple (change)='openFile($event)'>
openFile(event) {
let input = event.target;
for (var index = 0; index < input.files.length; index++) {
let reader = new FileReader();
reader.onload = () => {
// this 'text' is the content of the file
var text = reader.result;
}
reader.readAsText(input.files[index]);
};
}
It is very basic example of how you can do it.