Konstantin Konstantin - 2 months ago 27
HTTP Question

node-fetch receives empty body

I'm writing unit-tests for a simple NodeJS application and for some reason I cannot retrieve response body. It gets proper response code (either 200 for successful requests or 422 for invalid ones) but body appears to be empty. Also, when I'm making exactly the same request with httpie it works like charm. Logging also shows that controller works as expected.

Any ideas or suggestions are welcome.

Here's the controller part:

function register (req, res) {
return _findUser({email: req.body.email})
.then(user => {
if (user) {
console.log('EMAIL TAKEN');
return Promise.reject({message: 'This email is already taken'});
}

let params = _filterParams(req.body);
if (_isRegistrationValid(params)) {
console.log('REGISTRATION VALID');
return params;
} else {
console.log('PARAMS INVALID');
return Promise.reject({message: 'Params invalid'});
}
})
.then(_createUser)
.then(_generateToken)
.then(token => {
console.log('SENDING TOKEN');
console.log(token);
res.send({token: token});
})
.catch(error => {
console.log('CATCH ERROR');
res.status(422).send(error);
});
}


Here's the test section:

it ('Returns token when data is valid', done => {
fetch(`http://localhost:${testPort}/api/register`, {
headers: {'Content-Type': 'application/json'},
method: 'POST',
body: JSON.stringify({email: 'test@test.com', password: 'password', confirmPassword: 'password'})
})
.then(response => {
assert(response.ok); // this part works ok
expect(response.body.token).to.exist; // this part fails
done();
})
.catch(done);
});


Here's the httpie output:

kpr$ http post localhost:4000/api/register email="rest@test.com" password="password" confirmPassword="password"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 941
Content-Type: application/json; charset=utf-8
Date: Sat, 08 Oct 2016 11:39:30 GMT
ETag: W/"3ad-uBdW+HLbY7L2gb65Y+zptQ"
X-Powered-By: Express

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9_long_token_string_2M"
}


Here's the test output:

REGISTRATION VALID
_createUser
(node:70495) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
_generateToken
SENDING TOKEN
eyJhbGciOiJIU_long_token_string_lmYA

0 passing (160ms)
2 pending
1 failing

1) Authorization Registration Returns token when data is valid:
AssertionError: expected undefined to exist
at fetch.then.response (test/auth-controller-spec.js:57:41)
at process._tickCallback (internal/process/next_tick.js:103:7)


Printing out response body from within fetch() shows some huge object:

PassThrough {
_readableState:
ReadableState {etc...}
}

Answer

You need to try response.json() instead of response.ok which will return the response in a proper way in your case.

Hope this helps!