Skip to content

How to wait for the result of writeHandler in a formidable file upload request? #977

Open

Description

@itinance

I want to use formidable to upload files directly to S3. Following the official example it works just fine. However, I want to await the upload process and return the final URL of the uploaded file inside of the Http-Request to my client. And this seems to be a a challenge due to the limited nature of how fileWriteStreamHandler needs to be typed.:

const s3Client = new AWS.S3({
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_KEY,
  },
});

const uploadStream = (file) => {
  const pass = new PassThrough();
  s3Client.upload(
    {
      Bucket: 'demo-bucket',
      Key: file.newFilename,
      Body: pass,
    },
    (err, data) => {
      console.log(err, data);
    },
  );

  return pass;
};

const server = http.createServer((req, res) => {
  if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
    // parse a file upload
    const form = formidable({
      fileWriteStreamHandler: uploadStream,
    });

    form.parse(req, () => {
      res.writeHead(200);
      res.end();
    });

    return;
  }

form.parse returns immediately, no matter how long the S3-upload process works under the hood.

I tried to use a promise and await but the function type of uploadStream must not return a promise.

Type '(file: any) => Promise<any>' is not assignable to type '(file?: VolatileFile | undefined) => Writable'.

I want to achieve something like that:

form.parse(req, (uploadedFile: string) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ url: uploadedFile }, null, 2));
  res.end();
});

In order to do that, I need something like a return value from the uploadStream function where I would be able to receive the final information eventually. But since it is only returning a PassThrough-object, it seems to be very limited in that case for further approaches like mine.

Do you guys know how I can do that?

Activity

  1. GrosSacASac commented on Apr 28, 2024

    @GrosSacASac
    Contributor

    Have you tried to res.end inside the s3Client.upload callback (you need to have a ref to res there)

  2. itinance commented on Jun 24, 2024

    @itinance
    Author

    Have you tried to res.end inside the s3Client.upload callback (you need to have a ref to res there)

    Thanks for mentioning this! As for now, in my first tests, it works as expected. I will investigate it a little more and close this ticket once this approach has been tested more

  3. GrosSacASac commented on Oct 18, 2024

    @GrosSacASac
    Contributor

    Have you tested more ?

  4. added
    Priority: LowThis issue can probably be picked up by anyone looking to contribute to the project.
    Status: AvailableNo one has claimed for resolving this issue. Generally applied to bugs and enhancement issues.
    Type: QuestionA query or seeking clarification. Probably doesn't need the attention of everyone.
    Area: streamsThings related to handling streams, and bugs around them.
    Area: filesThings related to handling files, names, etc.
    on Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: filesThings related to handling files, names, etc.Area: streamsThings related to handling streams, and bugs around them.Priority: LowThis issue can probably be picked up by anyone looking to contribute to the project.Status: AvailableNo one has claimed for resolving this issue. Generally applied to bugs and enhancement issues.Type: QuestionA query or seeking clarification. Probably doesn't need the attention of everyone.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions