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
userIdfrommulter.diskStorage({ destination: (req) => {}):req.paramsdoesn't seem to exist as it always returnsundefined. - Getting
userIdfrommulter.diskStorage({ destination: (req) => {} }:req.bodyreturns an object with the request body but it does not include theuserIdas that is passed throughctx.params. - Running the
editUserfunction before multer and addinguserIdtoctx.file/ctx.request.bodyin it in hopes that it shows up inmulter.diskStorage'sreqparam.
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!