Så jeg tror, dit problem er på denne linje:
new_project.picture.data = fs.readFileSync(req.body.picture[0]);
Og det er mongoDB-tabelkolonnen, du indsætter data
ind i det giver dig den fejl. Den forventer en streng eller buffer, og du gav den et File-objekt.
Du kan få en base64 byte streng ved hjælp af hvad jeg postede her , som jeg vil prøve at integrere med din kode nedenfor:
Du skal sikre dig, at du har en variabel til at indsamle dine filer. Sådan har jeg sat toppen af min side op:
import React from 'react'
import Reflux from 'reflux'
import {Form, Card, CardBlock, CardHeader, CardText, Col, Row, Button } from 'reactstrap'
import actions from '~/actions/actions'
import DropZone from 'react-dropzone'
// stores
import SomeStore from '~/stores/someStore.jsx'
Reflux.defineReact(React)
export default class myUploaderClass extends Reflux.Component {
constructor(props) {
super(props);
this.state = {
attachments: [],
};
this.stores = [
SomeStore,
]
....
Bind derefter nye funktioner:
....
this.getData = this.getData.bind(this);
this.processFile = this.processFile.bind(this);
this.errorHandler = this.errorHandler.bind(this);
this.progressHandler = this.progressHandler.bind(this);
} // close constructor
Derefter arbejder vi på at levere bytes til attachments
og sende det til new_project.picture.data
. For mig bruger jeg en funktion, der kører onDrop
af DropZone ved hjælp af onDrop={this.uploadFile}
. Jeg kan ikke rigtig fortælle, hvad du laver, fordi jeg ikke har nogen anelse om, hvad filesToUpload
hentyder til. Min uploadFile
ser sådan ud:
uploadFile(event){
this.setState({
files: event,
});
document.getElementById('docDZ').classList.remove('dragover');
document.getElementById('progress').textContent = '000';
document.getElementById('progressBar').style.width = '0%';
this.state.files = event; // just for good measure
for (let i = 0; i < this.state.files.length; i++) {
const a = i + 1;
console.log('in loop, pass: ' + a);
const f = this.state.files[i];
this.getData(f); // this will load the file to SomeStore.state.attachments
}
}
og dette ville være getData
funktionen kørte for hver fil, der blev droppet/føjet til DropZone:
getData(f) {
const reader = new FileReader();
reader.onerror = this.errorHandler;
reader.onprogress = this.progressHandler;
reader.onload = this.processFile(f);
reader.readAsDataURL(f);
}
Derefter processFile()
fra onload
kører:
processFile(theFile) {
return function(e) {
const bytes = e.target.result.split('base64,')[1];
const fileArray = [];
// *** Collect any existing attachments ***
// I found I could not get it from this.state, but had to use
// my store, instead
if (SomeStore.state.attachments.length > 0) {
for (let i=0; i < SomeStore.state.attachments.length; i++) {
fileArray.push(SomeStore.state.attachments[i]);
}
}
// Add the new one to this.state
fileArray.push(bytes);
// Update the state
SomeStore.setState({
attachments: fileArray,
});
// This seemed to automatically add it to this.state, for me.
}
}
Når du har det, bør du være i stand til at gøre:
new_project.picture.data = this.state.attachments[0];
Hvis ikke, kan du af en eller anden grund prøve at kalde dette inde i exports.create_a_project()
, som det første du gør:
getData(req.body.picture[0]);
Dette kan endda fungere uden at skulle ændre din onDrop
rutine fra det du har. Og hvis this.state.attachments
ikke har noget, dine SomeStore.state.attachments
absolut burde, forudsat at du har gemt dette i en mappe kaldet stores
som someStore.jsx
.
import Reflux from 'reflux'
import Actions from '~/actions/actions`
class SomeStore extends Reflux.Store
{
constructor()
{
super();
this.state = {
attachments: [],
};
this.listenables = Actions;
this.baseState = {
attachments: [],
};
}
onUpdateFields(name, value) {
this.setState({
[name]: value,
});
}
onResetFields() {
this.setState({
attachments: [],
});
}
}
const reqformdata = new SomeStore
export default reqformdata
Yderligere funktioner
errorHandler(e){
switch (e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
alert('File not found.');
break;
case e.target.error.NOT_READABLE_ERR:
alert('File is not readable.');
break;
case e.target.error.ABORT_ERR:
break; // no operation
default:
alert('An error occurred reading this file.');
break;
}
}
progressHandler(e) {
if (e.lengthComputable){
const loaded = Math.round((e.loaded / e.total) * 100);
let zeros = '';
// Percent loaded in string
if (loaded >= 0 && loaded < 10) {
zeros = '00';
}
else if (loaded < 100) {
zeros = '0';
}
// Display progress in 3-digits and increase bar length
document.getElementById("progress").textContent = zeros + loaded.toString();
document.getElementById("progressBar").style.width = loaded + '%';
}
}
Og min DropZone &gældende statusindikator-markup:
render(){
const dropZoneStyle = {
height: "34px",
width: "300px",
border: "1px solid #ccc",
borderRadius: "4px",
};
return (
<Form>
<Col xs={5}>
<DropZone type="file" id="docDZ"
onDrop={this.uploadFile}
onDropRejected={this.onDropRejected}
onClick={this.handleUploadClick}
onChange={this.handleChange}
onDragEnter={this.handleDragEnter}
onDragLeave={this.handleDragLeave}
accept=".doc, .docx, .gif, .png, .jpg, .jpeg, .pdf"
multiple="true"
maxSize={999000}
style={dropZoneStyle}>
{'Click HERE to upload or drop files here...'}
</DropZone>
<table id="tblProgress">
<tbody>
<tr>
<td><b><span id="progress">000</span>%</b> <span className="progressBar"><span id="progressBar" /></span></td>
</tr>
</tbody>
</table>
</Col>
</Row>
</Form>
)
} // close render
} // close class
Og CSS:
.progressBar {
background-color: rgba(255, 255, 255, .1);
width: 100%;
height: 26px;
}
#progressBar {
background-color: rgba(87, 184, 208, .5);
content: '';
width: 0;
height: 26px;
}
Andre funktioner du mangler:
handleUploadClick(){
return this.state;
}
handleChange(){
this.state.errors.fileError = "";
}
handleDragEnter(event){
event.preventDefault();
document.getElementById("docDZ").classList.add("dragover");
}
handleDragLeave(event){
event.preventDefault();
document.getElementById("docDZ").classList.remove("dragover");
}
onDropRejected(files){
const errors ={}
let isAlertVisible = false;
for(let i=0, j = files.length; i < j; i++){
const file = files[i];
const ext = file.name.split('.').pop().toLowerCase();
//console.log(ext)
if(this.isFileTypeValid(ext)===false){
errors.fileError = "Only image files (JPG, GIF, PNG), Word files (DOC, DOCX), and PDF files are allowed.";
isAlertVisible = true;
}
if(ext === "docx" || ext ==="gif" || ext ==="png" || ext ==="jpg" || ext ==="jpeg" || ext ==="pdf" || ext ==="doc" && file.size > 999000){
errors.fileError = "Exceeded File Size limit! The maximum file size for uploads is 999 KB.";
isAlertVisible = true;
}
this.setState({
"errors": errors,
"isAlertVisible": isAlertVisible,
})
}
}