Home > Software design >  How do I make express middleware in class?
How do I make express middleware in class?

Time:01-21

I currently use multer middleware like below

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "public");
  },
  filename: function (req, file, cb) {
    cb(null, req.params.id   "_"   file.originalname);
  },
});


export const multerUploadSingle = (req: Request, res: Response, next: NextFunction) => {
  const upload = multer({ storage: storage }).single("file");

  upload(req, res, (error: unknown) => {
    if (error instanceof multer.MulterError) {
      const message = `file upload fail: ${error.message}`;
      next(new HttpException(message, HttpStatus.BadRequest));

    } else if (error instanceof Error) {
      const message = `file upload fail: ${error.message}`;
      next(new HttpException(message, HttpStatus.InternalServerError));

    } else {
      // upload success
      next();
    }
  });
}

and use in router like this

FileRouter.post("/upload/:id", multerUploadSingle, (req, res) => {...});

However, I felt I want to refactor this middleware in class, and rewrote the code like this,

export class Multer {
  private readonly storage: multer.StorageEngine;

  constructor() {
    this.storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, "public");
      },
      filename: function (req, file, cb) {
        cb(null, req.params.id   "_"   file.originalname);
      },
    });
  }

  uploadSingle(req: Request, res: Response, next: NextFunction) {
    const upload = multer({ storage: this.storage }).single("file");
  
    upload(req, res, (error: unknown) => {
      if (error instanceof multer.MulterError) {
        const message = `file upload fail: ${error.message}`;
        next(new HttpException(message, HttpStatus.BadRequest));
  
      } else if (error instanceof Error) {
        const message = `file upload fail: ${error.message}`;
        next(new HttpException(message, HttpStatus.InternalServerError));
  
      } else {
        // upload success
        next();
      }
    });
  }
}
const multer = new Multer();
FileRouter.post("/upload/:id", multer.uploadSingle, (req, res) => {...});

With my short knowledge, I think both case should have the same result, but the latter case which uses class made middleware doesn't work at all. It's seems method "uploadSingle" is never called, thus multer not uploading the file.

Did I make any mistake with class usage? or is it just express can only use function defined middleware?

CodePudding user response:

Your code should follow the MVC pattern. You can do stuff like this:

routerFile.js

const upload = require("../../configs/multer");
const postController = require("../../controllers/postController");

const multiUploadEvent = upload.fields([
    { name: "images", maxCount: 2 },
    { name: "video", maxCount: 2 }
]);
router.post("/add-event-post", multiUploadEvent, postController.addEventPost);
module.exports = router;

multer.js

const multer = require('multer');

const multerFilter = (req, file, cb) => {
    console.log("Mime type :", file.mimetype.split('/')[0]);
    if (file.mimetype.split('/')[0] === 'image' || file.mimetype.split('/')[0] === 'video' || file.mimetype.split('/')[0] === 'audio') {
        cb(null, true);
    } else {
        cb(new Error('Please upload img, audio, or video file only.'), false);
    }
};
const storage = multer.memoryStorage();
const upload = multer({
    storage: storage,
    fileFilter: multerFilter,
    limits: {
        fileSize: , 50 * 1024 * 1024// 50 Mb
    },
});
module.exports = upload;

postController.js

const addEventPost = async (request, response) => {
    try {
        let { title, ..... } = request.body;
        const images = request.files.images;
        const video = request.files.video;

        
        console.log(title);
        console.log(images);
        console.log(videos);
        //upload to services likes aws and save to database
        .
        .
        .
        return response
           .status(200)
           .json({
                  message: "Event post added successfully"
            });

} catch (error) {
    console.log(error);
    response.status(500).json({
        error: "Something went wrong",
    });
}

}

  • Related