Search code examples
javascriptnode.jsexpressmulter

Integrating Multer into my express backend that has router and controller structure issue


I am building a backend for a project of mine. I currently have my server/routers/controllers setup for the backend. I am creating the profile section of my project. I have profile pictures that I am trying to save when a user submits his profile. One part of of the profile is the profile picture. I am currently sending the profile picture from the react frontend to the express backend. The file is being sent correctly, but I am having issues saving the images on my local server when it is submitted.

I am currently trying to integrate multer into the project, but it is not storing anything and I am having trouble understanding how to integrate it with the lack of documentation. I do have routers and controllers setup which is making it a bit more triky. Can someone help... Here is the code

server:

...
const path = require('path');
const multer = require('multer');
const fileUpload = require('express-fileupload');

const app = express();
const upload = multer({dest:'../../client/static/images/ProfilePictures'})
...
app.use(cors());
app.use(cookieParser())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended : true }));
app.use(session({
  secret: 'helloworld',
  cookie: {maxAge: 60000},
  saveUninitialized: false,
}))
app.use(morgan('dev'))
app.use(fileUpload());
...
app.use('/api/auth', AuthenticationRouter)
app.use('/api/user', UserRouter)
app.use('/api/profile', ProfileRouter)

Routers:

const router = require("express").Router()
const profileController = require("../../controllers/UserControllers/ProfileController.js");

router
  .route('/')
  .get(profileController.get)
  .post(profileController.post)
  .delete(profileController.delete)
  .patch(profileController.patch)

module.exports = router;

controller:

const Profile = require("../../models/UserModels/Profiles.js")
const User = require('../../models/UserModels/Users.js')
...
  post:(req, res) => {
    console.log(req.files.profile_pic.name)
    let body = req.body
    let file = req.files.profile_pic
    Profile.create({
      profile_pic: file.name,
      f_name: body.f_name,
      l_name: body.l_name,
      bio: body.bio,
      location: body.location,
      sm_facebook: body.sm_facebook,
      sm_instagram: body.sm_instagram,
      sm_twitter: body.sm_twitter,
      sm_website: body.sm_website,
      followers: body.followers,
      following: body.following,
      photos: body.photos,
      downloads: body.downloads,
      edits: body.edits,
      userId: body.userId
    })
    .then((data) => {
      res.send(data).status(200)
    })
    .catch((err) => {
      console.error(err)
      res.send(err).status(400)
    })
  },

How do I integrate the upload if I am using router and controllers. All the examples just show the entire server processing on a single page which makes sense. But nothing shows when it is broken up like so.


Solution

  • Express allows to define more than one handler per route. So you can simply add the multer middleware before you set your handler from the controller. So in Router.js, you can do something like:

    const multer = require('multer');
    const upload = multer({dest:'<TBD>'});
    
    const router = require("express").Router();
    const profileController = require("../../controllers/UserControllers/ProfileController.js");
        
    router
      .route('/')
      .get(profileController.get)
      .post(upload.single("<TBD>"), uploadprofileController.post)
      .delete(profileController.delete)
      .patch(profileController.patch)
    
    module.exports = router;
    

    Also it does not make a lot of sense to use both express-fileupload and multer. With above usage of multer I'd get rid of express-fileupload.