Reputation: 69
When I was trying to find the problem, in my research I came across someone's suggestion to use
res.write(foo1)
res.write(foo2)
res.end
Instead of
res.send(foo1)
res.send(foo2)
But that didn't work. I then tried using this to test it:
res.write(foo1)
res.end()
But this is giving me an error:
events.js:174
throw er; // Unhandled 'error' event
^
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer. Received type object
at write_ (_http_outgoing.js:595:11)
at ServerResponse.write (_http_outgoing.js:567:10)
at User.findOne (C:\Users\notan\GitHub\se3316-notansandwich-lab5\server\controllers\user.controller.js:46:33)
at C:\Users\notan\node_modules\mongoose\lib\model.js:4604:16
at C:\Users\notan\node_modules\mongoose\lib\query.js:4348:12
at process.nextTick (C:\Users\notan\node_modules\mongoose\lib\query.js:2850:28)
at process._tickCallback (internal/process/next_tick.js:61:11)
Emitted 'error' event at:
at C:\Users\notan\node_modules\mongoose\lib\model.js:4606:13
at C:\Users\notan\node_modules\mongoose\lib\query.js:4348:12
at process.nextTick (C:\Users\notan\node_modules\mongoose\lib\query.js:2850:28)
at process._tickCallback (internal/process/next_tick.js:61:11)
const User = require('../models/user.model')
const jwt = require('jsonwebtoken')
exports.user_create = function (req, res, next) {
let user = new User(
{
_id: Math.random().toString(36).substr(2, 5), // generate a random ID
email: req.body.email,
password: req.body.password,
firstName: req.body.firstName,
lastName: req.body.lastName,
role: "user"
}
);
user.save(function (err, registeredUser) {
if (err) {
return next(err);
}
else {
let payload = { subject: registeredUser._id}
let token = jwt.sign(payload, 'secretKey')
res.status(200).send({token})
}
})
}
exports.user_login = function (req, res, next) {
let userData = req.body
User.findOne({email: userData.email}, (err, user) => {
if (err) {
console.log(err)
}
else {
if (!user) {
res.status(401).send('Invalid email')
}
else if (user.password !== userData.password) {
res.status(401).send('Invalid password')
}
else {
let payload = {subject: user._id}
let token = jwt.sign(payload, 'secretKey')
//res.status(200).send({token})
res.status(200).write({token})
//let role = this.user.role
// res.status(200).write({role})
res.end()
}
}
})
}
Using this works
res.status(200).send({token})
But this does not
res.status(200).write({token})
res.end()
Upvotes: 3
Views: 4520
Reputation: 707786
In response to the title of your question:
Can I use res.send(foo) twice?
No, you cannot call that twice for the same request.
See the second part of the answer since the OP changed their question after I wrote this first part
In Express, you can only use res.send()
or res.json()
or res.end()
once per request. When you execute those, it sends the request. If you try to send more on the same request, it will do nothing and will show a warning in Express.
res.write()
can be called more than once, then followed by res.end()
when you are finally done with the request.
In your example:
res.status(200).send({token})
res.end()
The res.send()
already calls .end()
for you so trying to call it again is considered an error because the request has already been sent.
FYI, .status(200)
is not necessary. The default status is already 200 so res.send({token})
will already have a 200 status.
More Recent Answer for the Modified Question
Now that you've completely changed the question to be about res.write({token})
, that does not work because res.write()
requires a String
or a Buffer
as an argument and you were giving it an object. You would have to manually convert the object to JSON yourself:
res.type('application/json');
res.write(JSON.stringify({token}));
res.end();
And note that this also sets the appropriate content type. If your object is large with res.write()
you may also have to pay attention to the write buffer being full and listen for the drain
event. res.write()
is a much lower level facility (it's at the http level, not at the Express level) than the Express functions for sending data.
Built into Express, you can use res.send()
or res.json()
which are Express methods that will both that you passed an object, automatically convert it to JSON for you and set the content type to JSON also. It will also handle any buffer full issues in the write stream too.
res.send({token});
or, I prefer to be more explicit in my Express code with:
res.json({token});
And, if you're trying to send multiple pieces of data, you can put them into the same object:
res.json({token, role});
Upvotes: 8
Reputation: 4879
If you want to use res.write(argument)
you have to pass the argument as a string or Buffer, just like the error message says. To get the same effect just convert your response object to a string:
res.status(200).write(JSON.stringify({token}))
Upvotes: 0
Reputation: 2345
Calling res.status(200).send({ token })
ends the request and sends the object back to the client...
Since the request is now ended... Calling res.end()
generates the error...
You'd usually use res.end
if u were piping some data (usually binary) after several res.write
to close the pipe...
For more info... checkout Express' docs in the response object...
https://expressjs.com/en/api.html#res
Also... U can't send an object using res.write
...
From your error... it says that it inly accepts a string or buffer. If u want to send plain objects... res.send
or res.json
would be more appropriate...
Upvotes: 1
Reputation: 69
I found the solution: I can send multiple things in an res.send(...)
res.status(200).send({token, role})
Upvotes: 0