Vì vậy, tôi nghĩ rằng vấn đề của bạn nằm ở dòng này:
new_project.picture.data = fs.readFileSync(req.body.picture[0]);
Và đó là cột bảng mongoDB mà bạn đang chèn data
vào đó là mang lại cho bạn lỗi đó. Nó đang mong đợi một chuỗi hoặc Bộ đệm và bạn đã cấp cho nó một đối tượng Tệp.
Bạn có thể nhận chuỗi byte base64 bằng cách sử dụng những gì tôi đã đăng ở đây , mà tôi sẽ thử và tích hợp với mã của bạn, bên dưới:
Bạn cần đảm bảo rằng bạn có một biến để thu thập (các) tệp của mình. Đây là cách tôi thiết lập phần đầu trang của mình:
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,
]
....
Sau đó, liên kết các chức năng mới:
....
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
Sau đó, chúng tôi làm việc để cung cấp các byte cho attachments
và gửi nó tới new_project.picture.data
. Đối với tôi, tôi sử dụng một hàm chạy onDrop
của DropZone bằng cách sử dụng onDrop={this.uploadFile}
. Tôi thực sự không thể biết bạn đang làm gì vì tôi không có manh mối nào filesToUpload
đề cập đến. uploadFile
của tôi trông như thế này:
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
}
}
và đây sẽ là getData
chức năng chạy cho mỗi tệp được thả / thêm vào DropZone:
getData(f) {
const reader = new FileReader();
reader.onerror = this.errorHandler;
reader.onprogress = this.progressHandler;
reader.onload = this.processFile(f);
reader.readAsDataURL(f);
}
Sau đó, processFile()
từ onload
chạy:
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.
}
}
Khi bạn có điều đó, bạn sẽ có thể làm:
new_project.picture.data = this.state.attachments[0];
Nếu không, vì lý do nào đó, bạn có thể thử gọi nó bên trong exports.create_a_project()
, như điều đầu tiên bạn làm:
getData(req.body.picture[0]);
Điều này thậm chí có thể hoạt động mà không cần phải sửa đổi onDrop
của bạn thói quen từ những gì bạn có. Và nếu this.state.attachments
không có bất cứ thứ gì, SomeStore.state.attachments
của bạn chắc chắn nên làm, giả sử bạn đã lưu cái này vào một thư mục có tên là stores
dưới dạng 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
Chức năng bổ sung
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 + '%';
}
}
Và DropZone của tôi và đánh dấu chỉ báo tiến trình áp dụng:
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
Và 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;
}
Các chức năng khác mà bạn đang thiếu:
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,
})
}
}