What's the difference between "app.render" and "res.render" in express.js?

express, node.js

Solution

Here are some differences:

You can call `app.render` on root level and `res.render` only inside a route/middleware.

`app.render` always returns the `html` in the callback function, whereas `res.render` does so only when you've specified the callback function as your third parameter. If you call `res.render` without the third parameter/callback function the rendered html is sent to the client with a status code of `200`.

Take a look at the following examples.

`app.render`

app.render('index', {title: 'res vs app render'}, function(err, html) {
    console.log(html)
});

// logs the following string (from default index.jade)
<!DOCTYPE html><html><head><title>res vs app render</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>res vs app render</h1><p>Welcome to res vs app render</p></body></html>

`res.render` without third parameter

app.get('/render', function(req, res) {
    res.render('index', {title: 'res vs app render'})
})

// also renders index.jade but sends it to the client 
// with status 200 and content-type text/html on GET /render

`res.render` with third parameter

app.get('/render', function(req, res) {
    res.render('index', {title: 'res vs app render'}, function(err, html) {
        console.log(html);
        res.send('done');
    })
})

// logs the same as app.render and sends "done" to the client instead 
// of the content of index.jade

`res.render` uses `app.render` internally to render template files.

You can use the `render` functions to create html emails. Depending on your structure of your app, you might not always have acces to the `app` object.

For example inside an external route:

`app.js`

var routes = require('routes');

app.get('/mail', function(req, res) {
    // app object is available -> app.render
})

app.get('/sendmail', routes.sendmail);

`routes.js`

exports.sendmail = function(req, res) {
    // can't use app.render -> therefore res.render
}

Problem

Docs for `app.render`: Render a view with a callback responding with the rendered string. This is the app-level variant of `res.render()`, and otherwise behaves the same way. Docs for `res.render`: Render a view with a callback responding with the rendered string. When an error occurs `next(err)` is invoked internally. When a callback is provided both the possible error and rendered string are passed, and no automated response is performed. How can I figure out when to use which one?

Original source