danibrum
danibrum

Reputation: 529

Async functions on expressJS

I have a doubt related to async function on Express. I'm fetching some JSON from database and I'm getting the following error: Error: Can't set headers after they are sent.

I've read a little bit about it and it seems that it's related to the function having a Finished state or something like that.

I had the following code and it was crashing my application:

 router.get('/home', isAuthenticated, function(req, res){

    atendimentos.find({}, function(err, atendimentos) {
        if(!err){
            console.log(atendimentos);
            return res.json(atendimentos);
        }
    })


    res.render('home', {user: req.user}); 
})

But then I changed to this code:

 router.get('/home', isAuthenticated, function(req, res){

    //Added async to the function
    atendimentos.find({}, async function(err, atendimentos) {
        if(!err){
            console.log(atendimentos);
            return res.json(atendimentos);
        }
    })


    res.render('home', {user: req.user}); 
})

The application stopped crashing but the error continues. I don't know why. Maybe I could get some help handling this?

Thanks

Upvotes: 0

Views: 97

Answers (2)

J. Pichardo
J. Pichardo

Reputation: 3115

From the Docs:

res.render

Renders a view and sends the rendered HTML string to the client.

res.json

Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().

So, as mentioned, you are sending two responses. If what you want is to have the atendimentos data in your view, you could pass it as a property of the object to res.render, something like:

 router.get('/home', isAuthenticated, function(req, res){

    //Added async to the function
    atendimentos.find({}, async function(err, atendimentos) {
        if(!err){
            console.log(atendimentos);

            res.render('home', {user: req.user, atendimentos}); 
        }
    });

});

Or you could just make a separate API call with fetch, XMLHttpRequest or any other way.

P.S. async has nothing to do with your issue, the reason it stopped crashing is that unhandled rejections do not make Node crash, this will change in a future release.

Upvotes: 1

Quentin
Quentin

Reputation: 944528

res.json() sends the response (formatted as JSON).

res.render() sends the response (using other formatting methods).

You can't send two responses to the same request.

Pick one.

Upvotes: 6

Related Questions