I need help with how to make the react-dropzone NPM package in making uploaded files show a preview on files other than Image files (*.png, *.jpg/jpeg, *.gif, etc. — those all generate a preview just fine).
Currently, when I use Dropzone for uploading accompanying files on a web form, if I Upload an Image file (*.png, *.jpg, etc.), the Preview we have set up shows just fine with a small thumbnail of the Uploaded file. (see pic below)
However, if I upload another type of file, say an MS-Outlook *.docx, *.xlsx, or say an Adobe Acrobat *.pdf, it just gives me a blank box with a broken file image and whatever alt="..."
text I had put in there, in this case, "Uploaded File Preview." (see pic below)
The code we are using was copied nearly verbatim from the Preview example on the React Dropzon Web Site, so I'm wondering if I missed something here?
Here's what I've tried —
- Create a
react-dropzone
<Dropzone>
page, with have it set to accept any file type, and giving it the ability to do Previews with the code from https://react-dropzone.js.org/#previews, having the "Preview"<aside>
at the bottom of the<Dropzone>
section of the code. - Drag and Drop any sort of Image file (*.png, *.jpg or *.jpeg, *.gif, etc.).
- Look at the Preview that appears (should be ok, a thumbnail of the image file).
- Now Drag and Drop any other sort of file (.doc, .xls, *.pdf, etc.) onto the
<Dropzone>
. - Look at the Preview that appears for that file (should be blank w/ a "broken file" image and whatever
alt="..."
text you have in there to describe the file).
Dropzone gets imported at the top of the file—
import React, { Component, /* useCallback */ } from "react";
...
import Dropzone from "react-dropzone";
...
Styling/CSS Code for Thumbnails —
...
const thumbsContainer = {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
marginTop: 16
};
const thumb = {
display: "inline-flex",
borderRadius: 2,
border: "1px solid #eaeaea",
marginBottom: 8,
marginRight: 8,
width: 100,
height: 100,
padding: 4,
boxSizing: "border-box"
};
const thumbInner = {
display: "flex",
minWidth: 0,
overflow: "hidden"
};
const img = {
display: "block",
width: "auto",
height: "100%"
};
...
The onDrop()
callback function—
...
onDrop = (acceptedFiles, rejectedFiles) => {
let files = acceptedFiles.map(async file => {
let data = new FormData();
data.append("file", file);
let item = await axios
.post("form/upload", data, {
headers: {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
return Object.assign(file, {
preview: URL.createObjectURL(file),
filename: response.data.filename
});
})
.catch(err => {
let rejects = rejectedFiles.map(async file => {
let data = new FormData();
await data.append("file", file);
console.log("There was an error while attempting to add your files:", err);
console.log("The files that were rejected were:\n", rejects.join('\n'));
})
});
return item;
});
Promise.all(files)
.then(completed => {
let fileNames = completed.map(function(item) {
return item["filename"];
});
this.setState({ files: completed, fileNames: fileNames });
})
.catch(err => {
console.log('DROPZONE ERROR:', err);
});
};
...
And the actual JSX code using <Dropzone>
in the React.JS return()
—
...
<Form.Field>
<label>Upload Files or Screenshots</label>
<Dropzone accept={acceptedFileTypes} onDrop={this.onDrop}>
{({ getRootProps, getInputProps, isDragActive }) => {
return (
<div
{...getRootProps()}
className={classNames("dropzone", {
"dropzone--isActive": isDragActive
})}
>
<input {...getInputProps()} />
{isDragActive ? (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">Drop Files Here.</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
) : (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">
Drag and Drop Supporting Files here to Upload.
</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
)}
</div>
);
}}
</Dropzone>
<aside style={thumbsContainer}>{thumbs}</aside>
</Form.Field>
...
Expected behavior —
I would prefer all file types to generate a correct preview.
My Set-up —
- MacBook Pro 13-Inch 2018
- 2.7 GHz Intel Core i7 processor
- 16 GB 2133 MHz LPDDR3 RAM memory
- MacOS version 10.14.4
- React & React-DOM versions 16.5.2
- Node.JS version 10.15.2
- yarn version 1.15.2
- React Dropzone version 10.1.4
- Google Chrome for Mac OS Browser version 74.0.3729.131 (Official Build) (64-bit)
- Upload to an AWS EC2 instance container server.
... So, am I doing something wrong so that previews on other files besides Images aren't working? Is this not a feature for anything but Image files? Please advise.
A couple other questions —
- If Previews are not able to be generated for files other than Image files with
react-dropzone
, is there a way to have Image Files generate Previews, but all other files just list the File name being uploaded and such, as in the some of the other examples on your React Dropzone Web Site? If so, how do you switch between the two to have both as you drag & drop files onto the<Dropzone>
? - In our code, which, again, we copied nearly verbatim from your examples at the React Dropzone Web Site, we have noticed that when you drag and drop on set of files onto the
<Dropzone>
, and then attempt to drag and drop a second time, that wipes the first set of files from being uploaded and replaces them with the new files just dropped on the<Dropzone>
. Is there a way to have the<Dropzone>
cumulatively add files on each time they are dropped there, not just wipe out the previous files and replace with the new? If so, what are the steps to do that, please? - Is there a way, in the case of having the blank box File Preview for all other files, to get rid of the "Broken File" icon?
I do appreciate any constructive reply, please. Thank you in advance.