sql >> Databáze >  >> NoSQL >> MongoDB

převod z blobu na binární a jeho uložení do mongodb

Takže si myslím, že váš problém je v tomto řádku:

new_project.picture.data = fs.readFileSync(req.body.picture[0]);

A je to sloupec tabulky mongoDB, který vkládáte data do toho vám dává tu chybu. Očekává řetězec nebo Buffer a vy jste mu dali objekt File.

Base64 bajtový řetězec můžete získat pomocí co jsem zde zveřejnil , který se pokusím integrovat do vašeho kódu níže:

Musíte se ujistit, že máte proměnnou pro shromažďování souborů. Takto mám nastavenou horní část stránky:

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,
    ]
    ....

Poté svažte nové funkce:

    ....
    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

Poté pracujeme na dodání bajtů do attachments a jeho odeslání na new_project.picture.data . Pro mě používám funkci, která spouští onDrop DropZone pomocí onDrop={this.uploadFile} . Opravdu nemohu říct, co děláte, protože nemám ponětí, co filesToUpload odkazuje na. Můj uploadFile vypadá takto:

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
  }
}

a toto by byl getData funkce byla spuštěna pro každý soubor zahozený/přidaný do DropZone:

getData(f) {
    const reader = new FileReader();
    reader.onerror = this.errorHandler;
    reader.onprogress = this.progressHandler;
    reader.onload = this.processFile(f);
    reader.readAsDataURL(f);
}

Poté processFile() z onload běží:

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.
  }
}

Jakmile to budete mít, měli byste být schopni:

new_project.picture.data = this.state.attachments[0];

Pokud ne, z nějakého důvodu to můžete zkusit zavolat uvnitř exports.create_a_project() , jako první věc, kterou uděláte:

getData(req.body.picture[0]);

To může dokonce fungovat, aniž byste museli upravovat onDrop rutina z toho, co máte. A pokud this.state.attachments nemá nic, vaše SomeStore.state.attachments rozhodně by měl, za předpokladu, že to máte uložené ve složce s názvem stores jako 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

Další funkce

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 + '%';
    }
  }

A moje DropZone a příslušné označení indikátoru průběhu:

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

A 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;
}

Další funkce, které postrádáte:

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,
    })
  }
}



  1. jak čtete všechny bajty, které přicházejí na tcp připojení?

  2. Ubuntu 16.04 systemd redis problémy s ulimit

  3. Dokážete najít jeden zápas jako první nebo poslední?

  4. MongoDB $setUnion