Check if res is sent / ended with Express - node.js

Using Express, how can I determine the response has been sent / that the response has been completely written to?
app.use((req,res,next) => {
if(res.ended){
//
}
if(res.finished){
//
}
});
how can I tell if res.end() has been called? I am looking for a boolean I can read on res.

Use res.writableEnded (docs).
res.finished is deprecated (see).

response.end() will set response.finished if it's been called, as per the documentation.

Related

Express server returns 200 for routes that have not even been defined

I have been facing a weird thing for several days and I had no luck of solving that so far. The problem is I have a React.js frontend , Node Express.js backend and MongoDB, when I'm making requests to /api/users/update-pwd with proper parameters using axios, it doesn't update the password, but it returns 200. Then, I tried some routes such as /api/users/psosp. To my surprise, It also returned 200. I couldn't find the reason for that. Any helpful tip is highly appreciated.
Axios.post("/users/update-password",{
password: n_pwd
}).then(
res => {
alert("Password Updated")
}
).catch(err => {
console.log(err)
alert("An error occured")
})
Make sure that you don't have code like this in your backend.
router.post('/users/:userId',(req,res)=>{
// some operations
res.send();
});
router.post('users/update-password',(req,res)=>{
// some operations
res.send();
});
What above does is that it doesn't matter whatever you use in place of * /users/*/
the first route will be called by default
and also make sure that you did not use
app.use('*',(req,res)=>{
// some operations
res.send();
})
For any API call irrespective of the path the above code will be called.

NODEJS - Can't set headers after they are sent

I have function, that executes when 'dataCompiled' event fires, it looks like his:
eventEmitter.on('dataCompiled', function () {
json = JSON.stringify({
conversations: convs
});
res.json(json).end();
return;
});
But when i refreshing page, i getting error
Error: Can't set headers after they are sent.
Finally figured out, need send json directly to end function, so it'll look like that:
res.end(json);
You don't need to stringify and end a call to res.json if I'm not mistaken:
eventEmitter.on('dataCompiled', function () {
return res.json({
conversations: convs
});
});
Are you sure you're not sending more data after this call? You shouldn't have to use res.end(): http://expressjs.com/en/4x/api.html#res.end .
If there is another place in your code you're sending more data to res it will give the error message you are receiving, res.end is not fixing the underlying problem.

Clearing Cooking in Express

I am setting a cookie like below in a post function.
res.cookie('sessionID', req.sessionID, { path: '/' });
It sets it fine...but I cannot seem to delete it. I am deleting it in a put function, because I want to update some data and then clear the cookie.
app.put('/data/completed/:info', jsonParser, function(req, res){
if (!req.body) return res.sendStatus(400)
res.clearCookie('sessionID', { path: '/' });
console.log(req.cookies.sessionID);
});
Obviously I am doing something wrong I just can't figure out what.
You are clearing cookie of response. But checking for request. Try to check console.log(res.cookies.sessionID);
So the issue wasn't with the clearing of the cookie it was with me not ending the response process. As clarified on the Express documentation.
res.end([data] [, encoding])
Ends the response process. This method actually comes from Node core,
specifically the response.end() method of http.ServerResponse.
Use to quickly end the response without any data. If you need to
respond with data, instead use methods such as res.send() and
res.json().
So when I put the res.end() function in the code, everything works as expected and the cookie clears.
app.put('/reset/:completed',function(req,res){
res.clearCookie('sessionID', { path: '/' });
res.end();
});

What is the difference between res.end() and res.send()?

I'm a beginner in Express.js and I'm confused by these two keywords: res.end() and res.send().
Are they the same or different?
First of all, res.send() and res.end() are not the same.
I would like to make a little bit more emphasis on some key differences between res.end() & res.send() with respect to response headers and why they are important.
1. res.send() will check the structure of your output and set header
information accordingly.
app.get('/',(req,res)=>{
res.send('<b>hello</b>');
});
app.get('/',(req,res)=>{
res.send({msg:'hello'});
});
Where with res.end() you can only respond with text and it will not set "Content-Type"
app.get('/',(req,res)=>{
res.end('<b>hello</b>');
});
2. res.send() will set "ETag" attribute in the response header
app.get('/',(req,res)=>{
res.send('<b>hello</b>');
});
¿Why is this tag important?
The ETag HTTP response header is an identifier for a specific version of a resource. It allows caches to be more efficient, and saves bandwidth, as a web server does not need to send a full response if the content has not changed.
res.end() will NOT set this header attribute
First of all, res.send() and res.end() are different.
res.send() will send the HTTP response. Its syntax is,
res.send([body])
The body parameter can be a Buffer object, a String, an object, or an Array. For example:
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });
See this for more info.
res.end() will end the response process. This method actually comes from Node core, specifically the response.end() method of http.ServerResponse. It is used to quickly end the response without any data. For example:
res.end();
res.status(404).end();
Read this for more info.
res.send() implements res.write, res.setHeaders and res.end:
It checks the data you send and sets the correct response headers.
Then it streams the data with res.write.
Finally, it uses res.end to set the end of the request.
There are some cases in which you will want to do this manually, for example, if you want to stream a file or a large data set. In these cases, you will want to set the headers yourself and use res.write to keep the stream flow.
In addition to the excellent answers, I would like to emphasize here, when to use res.end() and when to use res.send() this was why I originally landed here and I didn't found a solution.
The answer is very simple.
res.end() is used to quickly end the response without sending any data.
An example for this would be starting a process on a server:
app.get(/start-service, (req, res) => {
// Some logic here
exec('./application'); // dummy code
res.end();
});
If you would like to send data in your response then you should use res.send() instead:
app.get(/start-service, (req, res) => {
res.send('{"age":22}');
});
Here you can read more:
http://expressjs.com/en/4x/api.html#res.end
http://expressjs.com/en/4x/api.html#res.send
res.send() is used to send the response to the client where res.end() is used to end the response you are sending.
res.send() automatically call res.end() So you don't have to call or mention it after res.send()
res is an HttpResponse object which extends from OutgoingMessage. res.send calls res.end which is implemented by OutgoingMessage to send HTTP response and close connection. We see code here

How to execute jsonp response? Or how to make a string to a function call?

Following scenario:
I use Node.js to connect to an API.
I fire a request and get a jsonp response back.
This response look like:
processResponse({"LoginResponse":{"#token":"x"}})
That's it. Just that line: A string/object/text.
I have also a function processResponse()
processResponse(data){
console.log(data);
};
My Question: How to get that response executed, since it is just an object. I wish to 'parse' a string to a function call.
client.methods.loginRequest(loginArgs, function(data,response){
//response body as js object
console.log(data);
// processResponse({"LoginResponse":{"#token":"x"}})
// now I wish to execute it.
data; // this doesn't work
data.exec(); // this doesn't work
? // what else
});
function processResponse(data){
console.log(data);
};
I hope there is a way?

Resources