robmax
robmax

Reputation: 352

Multer doesn't see uploaded image

I want to save one image in single post request, which will be users's avatar to MongoDB, and also some users's information using package from npm called multer. Unfortunately only what I can see in console is error: TypeError: Cannot read property 'path' of undefined

register.pug

extends layout
block content
   h1 Register
   form(method='POST', action='/users/register')
    .form-group
      label Username:
      input.form-control(name='firstName', type='text')
    .form-group
      label Email:
      input.form-control(name='lastName', type='text')
    .form-group
      label Name:
      input.form-control(name='email', type='text')
    .form-group
      label Password:
      input.form-control(name='password', type='password')
    .form-group
      label Avatar:
      input.file(name='avatar', id='avatar' type='file')
    input.btn.btn-primary(type='submit',value='Submit')

register route

const upload = multer({ dest: 'uploads/avatars/' })
router.post('/register', upload.single('avatar'), (req, res, next) =>{
  const firstName = req.body.name;
  const lastName = req.body.name;
  const email = req.body.name;
  const password = req.body.name;
  let avatar = {
    path: req.file.path,
    orginalname: req.file.orginalname
  };

 let newUser = new User ({
   firstName: firstName,
   lastName: lastName,
   email: email,
   password: password,
   avatar: avatar
 });
}

newUser.save();
});

What is wrong with my code?

Upvotes: 1

Views: 1491

Answers (2)

C.Unbay
C.Unbay

Reputation: 2826

Uh, it took a while but i have found the reason, you need to give your files an extension. I will put here my code

This is my html file, I am using ejs modules in my app instead of jade

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form accept="image/x-png,image/gif,image/jpeg" enctype="multipart/form-data" action="/profile" method="post">
      <input type="file" name="avatar" value="">
      <input type="submit" name="" value="ssss">
    </form>
  </body>
</html>

Here is my app.js, if the destination path in cb function doesn't exist, it creates the directory for you.

Then here comes the filename, you need to give it an extension, it could be .png like i did, or you could do .jpeg, however you like, but it must be an image extension. Or you could just give it the extension that your client gives you.

Then we have our upload variable, which just sets up the pre-required functions for us.

var express = require('express')
var multer  = require('multer')
var app = express()

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, __dirname + '/uploads')      //you tell where to upload the files,
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + '.png')
  }
})

var upload = multer({storage: storage,
    onFileUploadStart: function (file) {
      console.log(file.originalname + ' is starting ...')
    },
});

app.set('view engine', 'ejs');

app.get('/', function(req, res, next){    
    res.render('mult');  //our html document
})

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  console.log(req.file);
  return false;
})

Upvotes: 2

AngelSalazar
AngelSalazar

Reputation: 3113

I believe you are missing this attribute

enctype="multipart/form-data"

in your form, give it a try !

Upvotes: 1

Related Questions