Getting `req.params` in multer's diskStorage functions

Viewed 384

all:

First time using Koa and multer. I've got the file uploading basics down but I can't seem to manage this particular use case:

I have my editUser route set up that takes the userId from ctx.params in order to identify the user being edited. Say I want to upload a user avatar picture and I want to store it in uploads/:userId/, how would I go about passing this userId to multer? I have tried the following and been unsuccessful thus far:

  • Getting the userId from multer.diskStorage({ destination: (req) => {}): req.params doesn't seem to exist as it always returns undefined.
  • Getting userId from multer.diskStorage({ destination: (req) => {} }: req.body returns an object with the request body but it does not include the userId as that is passed through ctx.params.
  • Running the editUser function before multer and adding userId to ctx.file/ctx.request.body in it in hopes that it shows up in multer.diskStorage's req param.

This is the code for my editUser controller:

const editUser = async (ctx, next) => {
  const { id } = ctx.params;

  await next();

  const user = await User.findByIdAndUpdate(
    id,
    { ...ctx.request.body, image: ctx.file.path },
    {
      new: true,
    }
  ).lean();
  if (user) {
    ctx.status = 200;
    ctx.body = user;
  } else {
    throw ERROR_MESSAGES.USER.NOT_FOUND;
  }
};

And here is the code for my multer.diskStorage() implementation:

const storage = multer.diskStorage({
  destination: (request, file, callback) => {
    const { id } = request.body; // undefined
    const { id } = request.params; // undefined
    const directory = `public/uploads/${id}/`;

    fs.exists(directory, (exists) => {
      if (!exists) {
        return fs.mkdir(directory, (error) => callback(error, directory));
      }
      callback(null, directory);
    });
  },

  filename: (request, file, callback) => {
    callback(null, file.originalname);
  },
});

This is the route that triggers the upload/edit:

router.post('/:id', upload.single('image'), editUser);

I'm not really sure if this is really the best approach or if there is a much simpler way of doing this. Any help will be greatly appreciated!

0 Answers
Related