Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doesn't send body in PUT request #165

Closed
wzup opened this issue Jun 20, 2017 · 9 comments
Closed

Doesn't send body in PUT request #165

wzup opened this issue Jun 20, 2017 · 9 comments

Comments

@wzup
Copy link

wzup commented Jun 20, 2017

No body in req.body. Neither of both sets req.body: field and send.
Why? What's wrong?

Set up:

const util = require('util');
const assert = require('assert');
const chaiHttp = require('chai-http');
const chai = require('chai');
const expect = chai.expect;
chai.use(chaiHttp);

chai.request('http://foo.com:3030')
    .put('/api/endpoind')
    .field('foo', 'http://foo.com:3030')
    .send({'bar': 'http://bar.com:3030'})
    .query({
        a: 'aaaaa',
        b: 'bbbbb',
        c: 'ccccc'
    })
    .end(function(err, res) {
        if (err) {
            console.error(err);
            done();
        }
        done();
    });

And req.body is an empty object

(req, res, next) => {
    console.log(req.body) // ==> {}
}
@meeber
Copy link
Contributor

meeber commented Jun 20, 2017

@wzup Check out #97 (comment) to see if it's related to your issue. I've never used this plugin personally and don't have time to dig in right now so it's hard for me to say for sure.

@wzup
Copy link
Author

wzup commented Jun 21, 2017

Both methods do not work, .field, .send.

I also found that the plugin doesn't set headers.

I set:

.set('content-type', 'application/json')

I receive:

  'user-agent': 'node-superagent/2.3.0',
  'content-type': 'multipart/form-data; boundary=--------------------------716330614312092759651257',

And on top of that, I get this when I run tests. Any test, every time:

Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

Just LOL. This plugin creates more issues than it solves.

@meeber
Copy link
Contributor

meeber commented Jun 21, 2017

chai-http is built on top of the superagent library. I believe the .field method is telling superagent that a multipart request is being performed; that's why your header isn't being respected. I have no doubt that the documentation is wrong/outdated; the creator of this plugin hasn't been active in 4+ years. This plugin (and Chai in general) is 100% community supported, and survives only on kind people making contributions when they find problems.

@wzup
Copy link
Author

wzup commented Jun 21, 2017

Here are approaches that work. The req.body is delivered full. Not as an empty object.

  1. This is as a form data.
.put('/path/endpoint')
.type('form')
.send({foo: 'bar'})
.end(function(err, res) {}

// headers received, set by the plugin apparently
  'accept-encoding': 'gzip, deflate',
  'user-agent': 'node-superagent/2.3.0',
  'content-type': 'application/x-www-form-urlencoded',
  'content-length': '127',

Many thanks to @barraponto. There is his answer here #97 (comment).

  1. This is as application/json:
.put('/path/endpoint')
.set('content-type', 'application/json')
.send({foo: 'bar'})
.end(function(err, res) {}

// headers received, set by the plugin apparently
  'accept-encoding': 'gzip, deflate',
  'user-agent': 'node-superagent/2.3.0',
  'content-type': 'application/json',
  'content-length': '105',

In both cases .send() is used. .field() doesn't work at all.

To authors.
How is it possible that there is nothing about .type('form') in your docs? Do you think we should guess how your puzzle works?

@meeber meeber closed this as completed Jun 21, 2017
@wzup
Copy link
Author

wzup commented Jun 21, 2017

More here

By default sending strings will set the Content-Type to application/x-www-form-urlencoded,

SuperAgent formats are extensible, however by default "json" and "form" are supported. To send the data as application/x-www-form-urlencoded simply invoke .type() with "form", where the default is "json".

  request.post('/user')
    .type('form')
    .send({ name: 'tj' })
    .send({ pet: 'tobi' })
    .end(callback)

@curtisnn
Copy link

curtisnn commented Aug 8, 2017

Just as a side note, I found that the reason my body parameters was empty was because I had called the appropriate middleware functions in the wrong order in the node.js express server.

For example, this left the body empty

var express = require('express');
var app = express();
var routesApi = require('./routes/routes');
var bodyParser = require('body-parser');

app.use('/api', routesApi);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

And this filled the body parameters the correct way

var express = require('express');
var app = express();
var routesApi = require('./routes/routes');
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routesApi);

@barraponto
Copy link
Contributor

@curtis-n I'd usually recommend against setting both json and urlencoded body parsers globally. The performance hit is minimal for running both by default, but I'd rather have my route defined as app.post('/api/comments', jsonParser, (req, res) => {...}) just to let the parser explicit. I see no problems with router-wise middlewares though.

@catalinberta
Copy link

catalinberta commented Sep 17, 2018

@wzup
You need to put a body parser before setting up the route with use

const bodyParser = require('body-parser');
const express = require('express');
const route = require('routes/myRoute');

const app = express();
app.use(bodyParser.json()); // BEFORE ADDING THE ROUTER 
app.use('/path', route);

chai.request(app)
				.post('/')
				.send({ login: 'test', password: 'test' })
				.end((err, res) => {
					expect(res).to.have.status(200);
					done();
				});

And then your route will receive the body

See SO answer: https://stackoverflow.com/questions/39470566/request-body-undefined-in-supertest

@ghost
Copy link

ghost commented Sep 5, 2022

Just as a side note, I found that the reason my body parameters was empty was because I had called the appropriate middleware functions in the wrong order in the node.js express server.

For example, this left the body empty

var express = require('express');
var app = express();
var routesApi = require('./routes/routes');
var bodyParser = require('body-parser');

app.use('/api', routesApi);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

And this filled the body parameters the correct way

var express = require('express');
var app = express();
var routesApi = require('./routes/routes');
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routesApi);

This work to me... TY @curtisnn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants