Search code examples
node.jsmongodbmulter

Failed to insert image into MongoDB server using NodeJS


I am trying to get the image when user submits the form and inserting it into mongoDB server.For image I am using Multer plugin but its showing me the error.Here is my code of NodeJS

const multer = require('multer');
mongoose.connect('mongodb://localhost:27017/mytable',{useNewUrlParser:true} )
.then(()=>
console.log("Mongodb connected"))
.catch(err => console.error("could not connected",err));
const Schema =new mongoose.Schema({
    name:String,
    email:String,
    lastname:String,
    pass:String,
    phonenumber:String,
    zipcode:String,
    birthdate:String,
    img:  {contentType:String,data:Buffer }

});
Schema.plugin(mongoosePaginate)
var user = mongoose.model('mytable', Schema);
//Multer for include image into directory
app.use(multer({ dest: '/public/'}).single('files'));
app.post('/save',(req,res)=>{

    console.log("image is" +req.body.img);
    var model = new user();
       model.name = req.body.name,
        model.email=req.body.email,
        model.lastname=req.body.lastname,
        model.pass=req.body.pass,
        model.phonenumber=req.body.phonenumber,
        model.zipcode=req.body.zipcode,
        model.birthdate=req.body.birthdate,
     /*   model.img.data = req.body.img,  */
        model.img.data = fs.readFileSync(req.files.userPhoto.path);
        newPic.image.contentType = 'image/png';
        model.save(function(err,doc){

    });
    res.json({result:'sucess'}); 
    res.end();
});

I just uploaded the required code. I am getting the error of Cannot read property 'userPhoto' of undefined .I don't know what should I write in fs.readFilesync.Please help me to insert image into a server .


Solution

  • You ask Multer to handle a .single() file that is expected to be referred to by the input name "files". According to the doc:

    The single file will be stored in req.file

    But you try to access req.files instead. (And it seems you're expecting this file to be referred to as "userPhoto", maybe?).

    See also what information Multer exposes to retrieve the uploaded file's path.

    Finally, you might want to restrict your middleware usage to the routes that need it.

    EDIT: a few comments

    // This tells the WHOLE app that:
    // when a request comes in, execute this
    app.use(
      // Multer will do:
      // when I'm given an incoming request (here it's every request)
      // then I'm looking for *one* file being uploaded
      // this file should be named "files" (i.e. client has <input type="file" name="files">)
      // if I find it, then I store it in /public
      multer({ dest: '/public/'}).single('files')
    );
    
    // This tells the app that:
    // if a request comes in for endpoint /save with method POST, this is the code to execute
    app.post('/save', (req, res) => {
      // in here, Multer will have been executed already
    });
    

    So:

    • does your form really names its file to be uploaded "files"? I'd guess your form names the file "userPhoto"... just a guess!
    • if such a file exists in the request, Multer documentation says that your route handler can access it in req.file (not req.files)
    • if not, Multer will just let the request pass (that's what middlewares do), so you won't have a req.file
    • if req.file is mounted on the request by Multer, it exposes several data fields, such as req.file.path

    I also hinted that you may not want to enable Multer for the whole app, but just for the routes that require it. Instead of a "global" app.use, you can define several times a route (or you could explicitly use the router, I don't see much of a difference), like:

    app.post('/save', multer(...));
    app.post('/save', (req, res) => {...});
    // which can also be written as
    app.post('/save', multer(...), (req, res) => {...});
    

    This way, all other routes do not consider file uploading, I'm sure I don't need to highlight how better this is.