2

Current Situation

In the front-end side of the application I have a simple form, from where I can get 3 parameters for the data before uploading it to the back-end:

The form submition function

e.preventDefault();
const data = new FormData(e.currentTarget) //contains a string key called title

data.append("file", JSON.stringify(file)) //file object
data.append("description", JSON.stringify(editorState)) //description object

handleSubmit(e, data)

To prevent any error, I have some client-side validations (cannot upload if some parameters are empty). This is how I fetch the data:

handleSubmit

await fetch(process.env.NEXT_PUBLIC_DR_HOST, {
    method: 'POST',
    body: body, //body is the data argument
}).then(res =>
{
    // window.location = res.url;
})

After that, the data will be sent to the server:

The server

router.post('/', upload.single('file'), validateDbData, tryAsync(async (req, res, next) =>

And using the multer middleware(upload.single('file')), the file will be uploaded respectively (storage).

The Problem

As you can see, after the upload.single('file') middleware, comes another one called validateDbData. This is the code for it:


const declarationSchema = Joi.object({
    title: Joi.string().required(),
    description: Joi.object().required(),
    file: Joi.object()
})

const { error } = declarationSchema.validate(
    req.body
)

console.log(error)

if (error)
{
    const msg = error.details.map(e => e.message).join(',') //
    throw new ServerError("Invalid Data", 400)
}
else
{
    next()
}

And if there is something wrong (say the title is empty) an error is thrown, so the server-side validation works. But, the upload.single('file') middleware is called before the validateDbData validation midleware. This means that even if there is an error and everything got canceled, the file remained uploaded in the cloud (storage).

Question

How can I validate the data inside the FormData on the server before uploading the file parameter to the cloud (storage)? The multer middleware accepts only multipart/form-data, so reversing the middleware order will not work.

Potential solution: express-fileupload

1 Answer 1

1

file remained uploaded in the cloud.

What is meant by cloud here? Multer lets you store the file onto a storage or on memory, and then subsequent middleware calls get the file and its info in the req.file field.

Your validator validateDbData requires the presence of the file, which leaves you with the option of housekeeping(to be performed in validateDbData middleware) if the form is not valid, depending on the use-case you should carefully chose where multer middleware stores the file, on memory or on a storage.

Sign up to request clarification or add additional context in comments.

2 Comments

I meant storage. The file is not required, so the validation does not depend on the presence of the file. The problem here is that the file is allready uploaded when the validation takes place, so if something is not right everything gets canceled, but I don't want to store the files and fill the storage with trash that is not being used. The point is that if the rest of the data (title, description) is valid the file should be uploaded, else the file should not be accepted.
@ArtiomO , thank you for helping me understand, from what you are mentioning , you could have a very lightweight POST endpoint, and all this endpoint does is validates the form body, For this to happen you will need to do the following : 1) Capture the form values, except the file from the client side 2) Create a POST endpoint which accepts these form fields as json and validates them 3) Upon success(200 OK) of endpoint called in 2) do as current scenario & send the form data along with the file in the subsequent request. This means client will chain 2 requests 1)validate, 2) submit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.