Ich denke also, Ihr Problem liegt in dieser Zeile:
new_project.picture.data = fs.readFileSync(req.body.picture[0]);
Und es ist die mongoDB-Tabellenspalte, in die Sie data
einfügen in das gibt Ihnen diesen Fehler. Es erwartet einen String oder Buffer und Sie haben ihm ein File-Objekt gegeben.
Sie können eine Base64-Byte-Zeichenfolge mit was ich hier gepostet habe , die ich versuchen werde, unten in Ihren Code zu integrieren:
Sie müssen sicherstellen, dass Sie eine Variable zum Sammeln Ihrer Datei(en) haben. So habe ich den oberen Rand meiner Seite eingerichtet:
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,
]
....
Dann neue Funktionen binden:
....
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
Dann arbeiten wir daran, die Bytes an attachments
zu liefern und an new_project.picture.data
senden . Für mich verwende ich eine Funktion, die onDrop
ausführt der DropZone mit onDrop={this.uploadFile}
. Ich kann nicht wirklich sagen, was Sie tun, weil ich keine Ahnung habe, was filesToUpload
ist bezieht sich auf. Meine uploadFile
sieht so aus:
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
}
}
und das wäre der getData
Die Funktion wurde für jede Datei ausgeführt, die in die DropZone abgelegt/hinzugefügt wurde:
getData(f) {
const reader = new FileReader();
reader.onerror = this.errorHandler;
reader.onprogress = this.progressHandler;
reader.onload = this.processFile(f);
reader.readAsDataURL(f);
}
Dann processFile()
aus dem onload
läuft:
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.
}
}
Sobald Sie das haben, sollten Sie in der Lage sein:
new_project.picture.data = this.state.attachments[0];
Wenn nicht, können Sie aus irgendeinem Grund versuchen, dies innerhalb von exports.create_a_project()
aufzurufen , als erstes:
getData(req.body.picture[0]);
Dies könnte sogar funktionieren, ohne dass Sie Ihr onDrop
ändern müssen Routine von dem, was Sie haben. Und wenn this.state.attachments
hat nichts, Ihre SomeStore.state.attachments
sollten Sie auf jeden Fall, vorausgesetzt, Sie haben dies in einem Ordner namens stores
gespeichert als 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
Zusatzfunktionen
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 + '%';
}
}
Und meine DropZone und anwendbares Markup für die Fortschrittsanzeige:
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
Und 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;
}
Andere Funktionen, die Sie vermissen:
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,
})
}
}