Search code examples
javascriptnode.jsexpressmulter

how to pass file names from multer to another middleware?


Multer takes the files i upload and puts it inside the file object so we can access it through the file but then the req.body.image is empty and i want to be able to pass the file.originalname to the req.body.image as path to the stored disk location. Now, i am working with multiple file here so i want to store their paths in the req object and access it inside another middle ware. I tried something like this

req.body.image.push(`path/${file.originalname}`)

which returns an error

TypeError: Cannot read property 'push' of undefined


Solution

  • TypeError: Cannot read property 'push' of undefined

    It looks like req.body.image isn't an Array but undefined when you're using push().

    When multer adds a single file to the request object, it adds them to the req.file property. You can then access req.file in subsequent middleware like in the below example. If you have multiple uploaded files then you would access the File Array req.files and iterate through the collection to access each file object.

    In your above code, you're modifying the req.body object and adding the property image, I wouldn't recommend changing the req.body object. It is good practice to not mutate things like the request headers or body. Instead, you can add a new property req.image to the request object.

    The below example uses Router Middleware to encapsulate the upload logic, (which should be kept to a single route usually) and then adds that middleware to an Express Server.

    imageUploadRouter.js

    // imageUploadRouter.js
    const router = require('express').Router()
    const multer = require('multer')
    const upload = multer({dest: 'uploads/'})
    
    router.use(upload.single('image'))
    router.use((req, res, next) => {
      if (!Array.isArray(req.image)) {
        req.image = []
      } 
    
      if (req.file) {
        req.image.push(`path/${req.file.originalName}`)
      }
    
      return next()
    })
    
    // add some additional routes for logic
    router.post('/', (req, res) => {
      // do something and respond
      // you can access req.image here too
      return res.sendStatus(201)
    })
    
    module.exports = router
    

    server.js

    // server.js
    const express = require('express')
    const ImageUploadRouter = require('./imageUploadRouter')
    
    const server = new Express()
    const port = process.env.PORT || 1337
    
    server.use('/images', ImageUploadRouter)
    server.listen(port, () => console.log(`Lisening on ${port}`))