Search code examples
node.jsexpressmulter

Multer nodejs - req.file is undefined


I am creating an app using Node, Express and ejs and multer for uploading images. Every time I submit the form, req.file is undefined. I've spent the entire day troubleshooting but can't figure out what I'm doing wrong.

HTML

<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
     <input class="img-file" type="file" name="image" required>
     <input class="submit" type="submit" value="Post" />
</form>

app.js

const path = require('path');
const express = require('express');
const morgan = require('morgan');
const bodyParser = require("body-parser");
const multer = require('multer');
const app = express();

app.use(express.static(path.join(__dirname, 'public')))
app.set('view engine', 'ejs'); 
app.set('views', path.join(__dirname,'resources/views'));
app.use(bodyParser.json());   
app.use(bodyParser.urlencoded({ extended: true }));

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "./image");
  },
  filename: function (req, file, cb) {
    console.log(req.file);

    cb(null, Date.now() + "-" + file.fieldname + ".png");
  },
});
const upload = multer({ storage: storage });
app.post("/post", upload.single("image"), (req, res) => {
      console.log(req.file);
});
app.get("/post", (req, res) => {
  res.render("post");
});
app.listen(, () => {
  console.log(`Example app listening at http://localhost:3000/login`);
});

Solution

  • You have few little bugs: first you forgot to add port and instead of login it should be post then we hit the correct address immediately, avoiding error Cannot GET /login

    app.listen(3000, () => {
      console.log(`Example app listening at http://localhost:3000/post`);
    });
    

    Project Folder & File structure:

    enter image description here


    app.js I added simple an error handler to the:

    app.post("/post", upload.single("image"), (req, res, next) => {}
    

    const path = require("path");
    const express = require("express");
    const morgan = require("morgan");
    const bodyParser = require("body-parser");
    const multer = require("multer");
    const app = express();
    
    app.use(express.static(path.join(__dirname, "public")));
    app.set("view engine", "ejs");
    app.set("views", path.join(__dirname, "resources/views"));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, "./image");
      },
      filename: function (req, file, cb) {
        console.log(req.file);
    
        cb(null, Date.now() + "-" + file.fieldname + ".png");
      },
    });
    const upload = multer({ storage: storage });
    
    // app.post("/post", upload.single("image"), (req, res) => {
    //   console.log(req.file);
    // });
    
    app.post("/post", upload.single("image"), (req, res, next) => {
      const file = req.file;
      if (!file) {
        const error = new Error("Please upload a file");
        error.httpStatusCode = 400;
        return next(error);
      }
      res.send(file);
      console.log("Success", req.file);
    });
    
    app.get("/post", (req, res) => {
      res.render("post");
    });
    
    app.listen(3000, () => {
      console.log(`Example app listening at http://localhost:3000/post`);
    });
    

    post.ejs

    <form action="/post" id="formPost" method="post" enctype="multipart/form-data">
      <input class="img-file" type="file" name="image" required />
      <input class="submit" type="submit" value="Upload File" />
    </form>
    

    output:

    enter image description here

    after selecting the file and pressing upload file:

    enter image description here

    VSCode output:

    enter image description here

    Works like a charm ;-)