0

I'm trying to send a file (.obj file) via formdata to my node server, it appears that everything is fine until the controller of the endpoint on the server throws an error that seems to be like the formdata parser is receiving an empty formdata object, here is the error in question. Now, here's my code:

Fron-end (where the request is being executed):

const data = new FormData();
data.append('file', this.props.filesSubmit, this.props.filesSubmit.name);
for (var pair of data.entries()) {
  console.log(pair[0] + ', ' + pair[1]);
}
await axios
  .post(
    'https://hushpuppys-3d-hub-api.herokuapp.com/api/v1/modelfiles/',
    data,
    {
      headers: {
        'Content-Type': undefined,
      },
    }
  )
  .then((res) => {
    console.log('File Upload Successful! Res: ', res);
  })
  .catch((err) => {
    console.log(err);
  });

Back-end endpoint Controller (Where request is received):

const AWS = require('aws-sdk');
const fs = require('fs');
const fileType = require('file-type');
const bluebird = require('bluebird');
const multiparty = require('multiparty');

// Keys Configuration to Access AWS
AWS.config.update({
  accessKeyId: '[I erased this]',
  secretAccessKey: '[I erased this]',
});

// Configuring AWS to work with promises
AWS.config.setPromisesDependency(bluebird);

// Creating S3 instance
const s3 = new AWS.S3();

// abstracts function to upload a file returning a promise
const uploadFile = (buffer, name, type) => {
  const params = {
    ACL: 'public-read',
    Body: buffer,
    Bucket: '[I erased this]',
    ContentType: type.mime,
    Key: `${name}.${type.ext}`,
  };
  return s3.upload(params).promise();
};

exports.fileUploaderController = (req, res) => {
  const form = new multiparty.Form();
  form.parse(req.body, async (error, fields, files) => {
    if (error) throw new Error(error);
    try {
      const path = files.file[0].path;
      const buffer = fs.readFileSync(path);
      const type = fileType(buffer);
      const timestamp = Date.now().toString();
      const fileName = `bucketFolder/${timestamp}-lg`;
      const data = await uploadFile(buffer, fileName, type);
      return res.status(200).send(data);
    } catch (error) {
      return res.status(400).send(error);
    }
  });
};

I want to also add the code of my app.js where other middlewares manipulate the body, maybe that's also relevant to solve the problem:

const express = require('express');

const modelRouter = require('./routes/modelRoutes');
const modelFilesRouter = require('./routes/modelFilesRoutes');
const cors = require('cors');

const app = express();

// MIDDLEWARES
app.use(cors());
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb' }));

// ROUTES
app.use('/api/v1/models', modelRouter);
app.use('/api/v1/modelfiles', modelFilesRouter);

module.exports = app;
  • Why do you set contentype to `undefined`? FormParser might need the actual contentype to be able to parse the body and the client may need it to correctly format the data before sending – derpirscher Sep 15 '20 at 21:12
  • I read in some other [question](https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post) thread here that if you set the contentype to `undefined` the browser automatically sets it with the boundaries, last time I checked on the request in the network tab the headers were actually there. Just to clarify, I actually did try setting the content-type to `'multipart/form-data'` this is _the way is supposed to be_ , but this get's me the same result, so I started tweaking with things like that just to get it to work. – Gustavo Rios Sep 15 '20 at 21:28
  • As you are using express. Have you tried using the multiparty-express (https://www.npmjs.com/package/multiparty-express) middleware instead of the multiparty module? I'm not sure, but maybe the other express middlewares may somehow interfere? Can you inspect your request in the network inspector of the browser? Is the body sent with the request? – derpirscher Sep 16 '20 at 08:18
  • Ok, so I tried 2 things, I used `express-multiparty` as you suggested, same error, same result. I also tried commenting out the `express.json()` and `express.urlencoded()` middlewares to see what happened and I got a CORS error for some reason, and I didn't even commented out the CORS middleware. I also checked the request boy in the browser and I got [this](https://pasteboard.co/JrkcFuL.png) it seems that the file is actually being sent. – Gustavo Rios Sep 16 '20 at 09:19

1 Answers1

0

Ok, I got this problem solved a few minutes ago. I was basically passing a wrong parameter in the form.parse() method in the fileUploaderController controller from the Controller file, the method form.parse() needs the whole req variable to be passed as a parameter, not the body of the request (req.body) as I did in the code I posted with the question.