Working with multipart formdata

Guys,

I’m having a few doubts to understand the request with multipart.
Here is my example: I have a form with one image (named image) and others input’s (name and email).

I processed my image like this example: S3 Single file upload, it’s worked, my image sucessfully uploaded to S3, but now how i deal with the others inputs? the text inputs?

I have to process the others with request.multipart.file(…).process()?
This: const data = Request.only([‘name’, ‘email’]); it’s not working.

You can simple use request.all()

Like this:

image

I tried, see:

    const { name } = request.all();
    console.log(name);

console: undefined

Lazy answer … try:

const name = request.input('name')

?

But how do you process the data on the server ?

  1. If in the classic way, you have a nice demo here
  2. If you are streaming the file then you may be interested in this.
2 Likes

I am streaming, but i have two text inputs, not only the image input.
I need to process the file too? like: request.multipart.field(…).process()?

const name = request.input(‘name’) also get undefined response!

1 Like

If you are streaming, then you are lucky because you will find a detailed answer through the second link I provided you above.

The second link is only uploading file, with only the file my function it’s working fine.
My problem it’s to deal with the other text data you know?

I have to to this:

  const body = {};
  await request.multipart.field((name, value) => {
    body[name] = value;
  });

to get the text data, i think have a easy way to do this…

is not that mentioned in the documentation ? I am not sure but I think I read it somewhere because I used it in the scenario (file + text data + streaming)

Use:

  1. request.multipart.field for text data
  2. request.multipart.file for the file

Later I will add more details if you need. But you have the keywords to search

Remember also that the request is processed only once in this context.

It is very important to understand when to use direct streaming vs using the traditional approach of tmp folder.

If you are planning to stream 20Kb's of files directly to s3, then you are simply making your life a lot harder. Stick to the default upload style and move the file from the tmp directory to s3.

If you are dealing with huge uploads with Gigabytes, then you should have a separate endpoint that deals just with file uploads and returns the URL of the uploaded file back, that you can use a reference with your normal forms.

1 Like

@virk
You have a example of how to move from tmp to s3?
i’m streaming because it’s the only way i found it to upload to s3.

@gustavopradoreis

I’m using this class to handle S3 uploads FileUpload.js, the class already change file name to an unique name, and move to tmp folder, etc…

I see you’re from Brazil, i’m Brazilian too. You can PM me in portuguese, and i can see if i can help you in any way.

@begueradj Take a look in the FileUpload.js… What do you think? Maybe i can create a provider for it? Or it’s unecessary?

1 Like

For the moment I starred and forked your code, I will have to look deeper into it before being able to judge your work :slight_smile: @un-versed

2 Likes

Hello,

The reason I’m here is because I’m facing a problem related to this topic.
I have a function that works with a request which has a header Content-Type: multipart-form.

The body of the request (data) is sent through an axios instance in a React App and it has this structure:

const fd = new FormData();
fd.append('questions', questions) //This is an array of objects
fd.append('file', myFile) //This is an uploaded file by the user

When I’m reading the request in the method at my controller I face this issue; I’m trying to store the input ‘questions’ which is an array of objects by doing this:

const questionsArray = request.input('questions');

However, when I print it in the console I get this:

console.log(questionsArray)
Outputs:
{ questions: '[object Object],[object Object],[object Object]' }

I have no way to access to each object of the array. It’s like the variable questionsArray is just storing an object with the key ‘questions’ and the rest ‘[object Object],[object Object],[object Object]’ was only a String an not the actual array of objects.

I must have the request’s header as multipart because I’m trying to store files too. In order to do so, I have to have access to the array of objects first.

Do you have and idea why I cannot access to it?

I already try to iterate with a forEach and for() loop through the questionsArray object.

I also tried using the next way, but it prints an empty object instead:

await request.multipart.field((name, value) => {
   if(name === 'questions') {
     questionsArray = value;
   }
  });

It doesn’t seem like a problem of how you access data in backend, more of a problem how frontend serializes it. (maybe missing JSON.stringify()?)
But I think it would be good to start new thread with some frontend coded too, since it’s not related to original post :wink:

You cannot append an array directly to a FormData object. You have loop through the array and append each element of the array individually.

const questions = ["What is your name?", "What is your hobby?", "Where are you from?"]

const fd = new FormData();

fd.append('file', myFile) //This is an uploaded file by the user

questions.forEach((question, index) => {
   fd.append(`question-${index}+1`, question)
})

From my experience with FormData objects, you might want to append the file before the strings.

1 Like