title: Upload file in node js with FormData multipart post request
body: <p>I don't understand what is wrong with this use case. If the body of the requested file is passed to form-data directly http upload doesn't work but if write to file and then pass file stream reader to form-data request works.</p>
  <p><strong>Test client</strong></p>
  <pre><code>import fs from &quot;fs&quot;;
  import FormData from &quot;form-data&quot;;
  import ky from &quot;ky-universal&quot;;
  
  const main = async () =&gt; {
    const { body } = await ky.get(
      &quot;https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf&quot;
    );
  
    const form = new FormData();
  
    // This works
    const writeStream = fs.createWriteStream(&quot;./tmp.pdf&quot;);
    body.pipe(writeStream);
    const fileStream = fs.createReadStream(&quot;./tmp.pdf&quot;);
    form.append(&quot;file&quot;, fileStream);
  
    // This doesn't work
    // form.append(&quot;file&quot;, body);
  
    form.append(&quot;param&quot;, &quot;param value&quot;);
  
    const res = await ky.post(`http://localhost:3030/upload`, {
      timeout: 20000,
      body: form,
    });
  
    const json = await res.json();
    console.log(json);
  };
  </code></pre>
  <p><strong>Test server</strong></p>
  <pre><code>// mkdir uploads
  // npm install express multer
  import express from &quot;express&quot;;
  import multer from &quot;multer&quot;;
  
  var upload = multer({ dest: &quot;uploads/&quot; });
  
  var app = express();
  
  app.post(
    &quot;/upload&quot;,
    upload.single(&quot;file&quot;),
    function (req, res, next) {
      console.dir(req.file);
      console.dir(req.body);
      res.json({ ok: true });
    }
  );
  
  app.listen(process.env.PORT || 3030);
  </code></pre>
  <p><a href="https://gist.github.com/davidnussio/8148b2296a476637bb7e4dae8cf52d44" rel="nofollow noreferrer">https://gist.github.com/davidnussio/8148b2296a476637bb7e4dae8cf52d44</a></p>
  <h1>UPDATE</h1>
  <p><strong>Workaround</strong></p>
  <p>Maybe related with <a href="https://github.com/sindresorhus/ky-universal/issues/25#issuecomment-691611572" rel="nofollow noreferrer">this issue</a> and maybe related to me working with node PassThrough streams but as workaround, instead to plug response directly to form-data to the post request i consume the stream to new buffer variable.</p>
  <pre><code>async function client() {
    const { body } = await ky.get(
      &quot;https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf&quot;
    );
  
    return new Promise((resolve, reject) =&gt; {
      const data = [];
      const writableStream = new stream.Writable({
        defaultEncoding: &quot;utf-8&quot;,
      });
  
      writableStream._write = (chunk, encoding, next) =&gt; {
        data.push(Buffer.from(chunk, encoding));
        next();
      };
  
      stream.pipeline(body, writableStream, (err) =&gt; {
        if (err) {
          return reject(err);
        }
        const form = new FormData();
  
        const buffer = Buffer.concat(data);
  
        form.append(&quot;file&quot;, buffer, { filename: 'tmp.pdf' });
        form.append(&quot;param&quot;, &quot;param-value&quot;);
  
        ky.post(url1, {
          timeout: 20000,
          body: form,
        })
          .json()
          .then((json) =&gt; resolve(json))
          .catch((error) =&gt; reject(error.message));
      });
    });
  }
  
  </code></pre>