score:0

Accepted answer

so i think your problem is in this line:

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

and it's the mongodb table column that you are inserting data into that is giving you that error. it's expecting a string or buffer and you gave it a file object.

you can get a base64 byte string using what i posted here, which i'll try and integrate with your code, below:

you'd need to ensure you have a variable to collect your file(s). this is how i have the top of my page set up:

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

then bind new functions:

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

then we work on supplying the bytes to attachments and sending it to new_project.picture.data. for me, i use a function that runs ondrop of the dropzone using ondrop={this.uploadfile}. i can't really tell what you're doing because i have no clue what filestoupload refers to. my uploadfile looks like this:

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

and this would be the getdata function ran for each file dropped/added to the dropzone:

getdata(f) {
    const reader = new filereader();
    reader.onerror = this.errorhandler;
    reader.onprogress = this.progresshandler;
    reader.onload = this.processfile(f);
    reader.readasdataurl(f);
}

then processfile() from the onload runs:

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

once you have that, you should be able to do:

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

if not, for some reason, you might try to call this inside exports.create_a_project(), as the first thing you do:

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

this might even work without having to modify your ondrop routine from what you have. and if this.state.attachments doesn't have anything, your somestore.state.attachments definitely should, assuming you have this saved to a folder called stores as 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

additional functions

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

and my dropzone & applicable progress indicator 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

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

other functions you're missing:

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

Related Query

More Query from same tag