Search code examples
node.jsfile-uploadmulter

file.size undefined in Multer


I'm using multer to handle a multi-file upload, and the middleware "filename", like this:

  filename: async (req, file, cb) => {
    console.log(Object.keys(file));
    ({ rows } = await db.query(`
    INSERT INTO public.files(
      uuid,
      nom,
      type,
      size
    )
    VALUES
    ($1, $2, $3, $4)
    RETURNING *`, [
      req.uuid,
      file.originalname,
      file.mimetype,
      file.size,
      // +req.headers["content-length"],
    ]));
    cb(null, uuid);
  },

The problem is that file.size remains undefined. I control that the size exists before sending the files to the API. When I check which properties are available (see the console.log), I only have 'fieldname', 'originalname', 'encoding', 'mimetype'.

If I use +req.headers["content-length"] it takes into account the size of all the request (all the files), and not only the current file.

Why can't I have the file size? Is it impossible or should I edit some setting I haven't found in the documentation?


Solution

  • Thanks to @traynor, here is what I did:

    I added a middleware after the upload:

    router.post('/',
      upload.array('files'),
      handleFiles,
      ...
    

    I simplified my upload:

    const storage = multer.diskStorage({
      destination: async (req, file, cb) => {
        let folder = config.get('api.files');
        req.uuid = uuid.v4();    
        folder += `/${req.uuid.charAt(0)}/${req.uuid.charAt(1)}/`;
        await fsPromises.mkdir(folder, { recursive: true });
        cb(null, folder);
      },
      filename: async (req, file, cb) => {
        cb(null, req.uuid);
      },
    });
    
    const upload = multer({ storage });
    

    And I handled the logic with the new middleware:

    const handleFiles = async (req, res, next) => {
      // my logic here, with req.files having f.size for each file
      // and f.originalname anf f.filename
    
      next();
    }