1

good evening.

I'm trying to create a POST request with a file and some data on a REST API I'm building using NodeJS. If not clear, my goal to this feature of the API is to save a register of a picture, so I'd like to send the picture file, the picture name and it's number on the same request.

I'm currently using Jest / supertest for testing and to test this specific functionality, I've tried the following:

    const response = await request(app)
      .post("/uploads/pics")
      .field("name", "PicureName")
      .field("number", "PictureNumber")
      .attach("file", picture);

I've read this from https://visionmedia.github.io/superagent/#multipart-requests

My problem is that I can't get the values of name and number on my request on my controller, so I can't use them to save the object.

I've tried many ways, such as:

req.body.name
req.name
req.field.name
req.query.name

but none of these worked for me.

I also tried printing the whole request, however I couldn't find anything related to name, number or field there.

Does anyone can tell what I'm doing wrong ?

zealous
  • 7,336
  • 4
  • 16
  • 36
palmeiira
  • 45
  • 1
  • 9
  • You need a middleware that parse the multipart/form-data to set the fields in the body. Check https://github.com/expressjs/multer and https://stackoverflow.com/questions/49029893/accessing-raw-post-data-in-express/49030208#49030208 – Mickael B. Jul 12 '20 at 15:36

1 Answers1

2

You should use https://github.com/expressjs/multer middleware for handling file upload. Then, req.body will hold the text fields, if there were any.

E.g.

index.js:

const express = require('express');
const multer = require('multer');
const app = express();

const upload = multer({ dest: 'uploads/' });
app.post('/uploads/pics', upload.single('file'), (req, res) => {
  console.log(req.body);
  console.log(req.file);
  res.sendStatus(200);
});

module.exports = app;

index.test.js:

const request = require('supertest');
const app = require('./');
const path = require('path');
const { expect } = require('chai');

describe('62862866', () => {
  it('should pass', async () => {
    const picture = path.resolve(__dirname, './test.jpg');
    const response = await request(app)
      .post('/uploads/pics')
      .field('name', 'PicureName')
      .field('number', 'PictureNumber')
      .attach('file', picture);
    expect(response.status).to.be.eq(200);
  });
});

integration test result:

  62862866
[Object: null prototype] { name: 'PicureName', number: 'PictureNumber' }
{ fieldname: 'file',
  originalname: 'test.jpg',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  destination: 'uploads/',
  filename: '181b96eb9044aac5d50c8c1e3159a120',
  path: 'uploads/181b96eb9044aac5d50c8c1e3159a120',
  size: 0 }
    ✓ should pass (84ms)


  1 passing (103ms)
Lin Du
  • 88,126
  • 95
  • 281
  • 483