Search code examples
node.jsexpressamazon-s3multermulter-s3

Multer req.file is undefined - using with Node/Express for image upload to s3


I know this question has been asked a lot, I've tried pretty much every answer to try to get this running but I keep getting undefined for req.file.

Code below:

services.imageUpload.js

const aws = require("aws-sdk");
const multer = require("multer");
const multerS3 = require("multer-s3");

aws.config.update({
  secretAccessKey: "XXXXXXXXXXXXX",
  accessKeyId: "XXXXXXXXXXXX",
  region: "XXXXXXX",
});
const s3 = new aws.S3();

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "XXXXXXXXX",
    metadata: function (req, file, cb) {
      cb(null, { fieldName: "TESTING_META_DATA" });
    },
    key: function (req, file, cb) {
      cb(null, req.s3key);
    },
  }),
});

module.exports = upload;

routes.imageUpload.js

const express = require("express");
const router = express.Router();
const upload = require("../services/imageUpload");

const singleUpload = upload.single("image");

router.post("/", function (req, res) {
  singleUpload(req, res, function (err) {
    return res.json({ request: req.file.location });
  });
});

module.exports = router;

index.js

const express = require("express");
const app = express();
const cors = require("cors");
const imageUpload = require("./routes/imageUpload");

//Middleware
app.use(cors());
app.use(express.json());

//Image upload
app.use("/upload-image", imageUpload);

app.listen(5000, () => {
    console.log("server is running on port 5000");
});

Help would be much appreciated! Quite frustrating. Currently testing API with postman and sending a POST request as form-data with a key of "image" and value of the uploaded image file.


Solution

  • In your index.js you can bring

    const upload = require("../services/imageUpload");
    

    at the top and then initialize the multer middleware here

    //Middleware
    app.use(cors());
    app.use(express.json());
    app.use(upload.single("image"))
    

    then in routes.imageUpload.js you can read the uploaded file like this

    router.post("/", function (req, res) {
        let fileDetails = req.files
        console.log(fileDetails )
        .
        .
        .
    });
    

    Or if you only need the uploader in your routes.imageUpload.js you can just use the middleware like this ,

    const express = require("express");
    const router = express.Router();
    const upload = require("../services/imageUpload");
    
    const singleUpload = upload.single("image");
    
    router.post("/",[singleUpload],function (req, res) {
        let fileDetails = req.files
        console.log(fileDetails )
        .
        .
        .
    });