'How to upload images on node js?

I am having issues getting any image data on the form in the ejs file after submitting. Upon debugging, there is a req.body.image which has the filename but req.file is undefined. I have tried many sites online detailing how to upload images but none seem to be working, any suggestions?

Part of the code in server.js file:

require("dotenv").config()
const express = require("express");
const cors = require("cors");
const path = require('path')
const app = express();
const mongoose = require("mongoose")
const fs = require('fs')
const multer = require('multer')

const fileupload = require("express-fileupload");
const Grid = require("gridfs-stream");
let gfs;
app.use(fileupload());
require('./routes/auth.routes')(app);
require('./routes/user.routes')(app);
app.use('/uploads', express.static('uploads'))
app.set('view engine', 'ejs');
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'static')));

app.use(cors(corsOptions));
app.use(express.json());
var storage = multer.diskStorage({
    destination: function(req,file,cb){
        cb(null, '../uploads/')
    },
    filename: function(req, file, cb) {
        cb(null, Date.now()+file.originalname)
    }
})
const fileFilter = (req,res,cb) =>{
    if(file.mimetype === "image/jpeg"||file.mimetype ==='image/png'){
        cb(null, true);
    }else{
        cb(null,false);
    }
}
var upload = multer({
    storage:storage,
    fileFilter: fileFilter
})
app.post('/makepost', upload.single('image'), async function(req, res, next){
    if(req.file)
    {
        const pathName=req.file.path;
        res.send(req.file.filename)
    }
    await db.post.create({
        "author": "",
        "title": req.body.title,
        "img": req.file,
        "description": req.body.description
    })
    res.render('pages/index', {loggedin: loggedin, test: test});

});

createpost.ejs page:

<!DOCTYPE html>
<html lang="en">
<head>
    <%- include('../partials/head'); %>
</head>
<body  class="u-body u-xl-mode"><div class="u-clearfix u-sheet u-valign-middle u-sheet-1">
        <%- include('../partials/navbar', {loggedin:loggedin}); %>
        <section>
            <h1 align="center">Create post</h1>
        </section>

        <div class="createpost">
            <form action="/makepost" method="post">
                <label for="title">
                    <!-- font awesome icon -->
                    <i class="fab fa-adversal"></i>
                </label>

                <input type="text" name="title" placeholder="Title" id="title" required>
                <br>
                <label for="description">
                    <i class="fa fa-paper-plane"></i>
                </label>

                <input type="text"  name="description" placeholder="Description" id="description" required>
                <br>
                <label for="image">Upload Image</label>
                <input type="file" id="image" name="image" required>
                <input type="submit" value="Upload post">
            </form>
        </div>

    </div>
<footer>
    <%- include('../partials/footer'); %>
</footer>
</body>
</html>


Solution 1:[1]

Add enctype='multipart/form-data' attr to the form. Whenever you have files inside a form it is required that you have this.

example:

<form action="/makepost" method="post" enctype="multipart/form-data">
...
</form>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mohammed Imran