'Keep getting req.file is undefined while uploading image using multer
I am trying to upload an image to my mongodb collection from the signup page using multer,but for some reason req.file always returns undefined. I've tried the methods provided in similar questions ,but to no avail. Here's my app.js code:
const express = require('express');
const mongoose = require('mongoose');
const cookieParser = require('cookie-parser');
const { checkUser, auth } = require('./middleware');
const bodyParser = require('body-parser')
const multer = require('multer')
const fs = require('fs')
const path = require('path')
const app = express()
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cookieParser());
app.set('view engine','ejs');
mongoose.connect(dbURI)
.then((result)=>app.listen(3000))
.catch((err)=>console.log(err))
var storage = multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,'uploads')
},
filename:(req,file,cb)=>{
cb(null,file.fieldname + '-' + Date.now())
}
});
var upload = multer({storage:storage});
app.post('/signup',upload.single('image'),async(req,res,next)=>{
console.log(req.file)
const details = {
email:req.body.email,
password:req.body.password,
username:req.body.username,
img: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
//const {email,password,username,img} = req.body
console.log(req.body)
try{
const user = await User.create(details)//({email,password,username,img});//
const token = createToken(user._id);
res.cookie('jwt',token,{httpOnly:true,maxAge:maxAge*1000});
res.status(201).json({user:user._id});
}
catch(err){
const errors = errorHandler(err);
res.status(400).json({errors});
}
})
This is my model.js:
const mongoose = require('mongoose');
const { isEmail } = require('validator');
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema({
email:{
type:String,
required:[true,'Please enter an email'],
unique:true,
lowercase:true,
validate:[isEmail,'Please enter a valid email']
},
password:{
type:String,
required:[true,'Please enter a password'],
minlength:[5,'Minimum password length is 5 characters'],
},
username:{
type:String,
required:[true,'Please enter an username'],
unique:true
},
img:{
data:Buffer,
contentType:String
}
});
userSchema.pre('save', async function(next) {
const salt = await bcrypt.genSalt();
this.password = await bcrypt.hash(this.password, salt);
next();
});
userSchema.statics.login = async function(email,password){
const user = await this.findOne({ email })
if(user){
const verify = await bcrypt.compare(password,user.password);
if (verify){
return user;
}
throw Error('incorrect password');
}
throw Error('incorrect email');
};
const User = mongoose.model('user',userSchema);
module.exports = User;
frontend signup.ejs code:
<body>
<form action="/signup" method="POST" enctype="multipart/form-data">
<h2>Sign Up</h2>
<label for="username">Username</label>
<input type="text" name="username">
<div class="username error"></div>
<label for="email">Email</label>
<input type="text" name="email" />
<div class="email error"></div>
<label for="password">Password</label>
<input type="password" name="password" />
<div class="password error"></div>
<label for="image">Upload a profile photo:</label>
<input type="file" id="image" name="image" />
<button>Sign Up</button>
</form>
<script>
const footer = document.querySelector('footer');
footer.style.bottom = '-200px'
// To display errors on the frontend
const form = document.querySelector('form');
const emailError = document.querySelector('.email.error');
const passwordError = document.querySelector('.password.error');
const usernameError = document.querySelector('.username.error');
form.addEventListener('submit',async (e)=>{
e.preventDefault()
emailError.textContent = '';
passwordError.textContent = '';
const email = form.email.value;
const password = form.password.value;
const username = form.username.value;
try{
const res = await fetch('/signup',{
method:'POST',
body:JSON.stringify({email,password,username}),
headers:{'Content-Type':'application/json'}
});
const data = await res.json();
console.log(data);
if (data.errors) {
emailError.textContent = data.errors.email;
passwordError.textContent = data.errors.password;
}
if (data.user) {
location.assign('/');
}
}
catch(err){
console.log(err);
}
})
</script>
</body>
</html>
Please help me out with this one, I've been struggling on it for more than a day now. Thank you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
