Search code examples
javascriptnode.jsexpressmulter

Multer: Different Storage Engines for multiple POST requests


I'm building an app to upload files to my server, I'm using multer to save files on the server's folders. I'm trying to make my /uploads route catch multiple files (currently only two images) and store them in different multer Storage Engines:

Storage Engines

const serumPresetsStorageCfg = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "./src/serum-presets");
    },
    filename: (req, file, cb) => {
        cb(null, Date.now() + "  --  " + file.originalname);
    },
});
const serumPresetsStorage = multer({storage: serumPresetsStorageCfg});

//**********************************************************************

const showcaseImageStorageCfg = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "./src/showcase-image");
    },
    filename: (req, file, cb) => {
        cb(null, Date.now() + "  --  " + file.originalname);
    },
});
const showcaseImageStorage = multer({storage: showcaseImageStorageCfg});

/uploads Route

app.post("/uploads", serumPresetsStorage.single("kit-image"), (req,res) => {
    console.log(req.file);});

app.post("/uploads", showcaseImageStorage.single("showcase-image"), (req,res) => {
    console.log(req.file);});

kit-image POST request works fine, however, when I try to make a POST request using showcase-image key on postman API I get the following error: MulterError: Unexpected field

I thought that specifying different keys on .single("") would allow me to catch different POST requests on the /uploads route, but that doesn't seem to be the case.

My question is... Is there a way I can get these different POST requests on /uploads and handle them separately with my different Storage Engines?


Solution

  • When you have same endpoint name on both request, there will be issue on same endpoint with different request.

    Unless you make changes on different route

    app.post("/uploads/serum-presets", serumPresetsStorage.single("kit-image"), (req, res) => {
      console.log(req.file);
      // Handle serum presets upload
    });
    
    app.post("/uploads/showcase-image", showcaseImageStorage.single("showcase-image"), (req, res) => {
      console.log(req.file);
      // Handle showcase image upload
    });
    

    OR

    Create a controller and put additional form-value in order to validate which request your plan to do. Based on form-value, you can call it separately.

    app.post("/uploads", (req, res, next) => {
      const fieldName = req.body.fieldName; // Get the field name from the request body
      switch (fieldName) {
        case "kit-image":
          serumPresetsStorage.single(fieldName)(req, res, next);
          break;
        case "showcase-image":
          showcaseImageStorage.single(fieldName)(req, res, next);
          break;
        default:
          // Handle invalid field name
          break;
      }
    }, (req, res) => {
      console.log(req.file);
      // Handle file upload based on field name
    });