Poni
Poni

Reputation: 11337

nodejs/express/ejs render() synchronous

res.render("index.ejs", {});

The above would be fine for simple cases.

How do I make EJS return the processed string as the function's return value? Make it work like this:

res.send(ejs.render("index.ejs", {}));

In other words - I want to nest/chain a few render() calls, NOT asynchronously.

Express doesn't seem to support this natively, or does it?
And if not, then how would I achieve it directly through EJS?

If you wonder why I prefer the "bad" way (synchronous) then I got one thing to say: Cache.
The templates are being cached anyway, so I don't mind the first load of the template to be slower (in just a few ms anyway).
This cost of single delay of a time fraction is no cost compared to having to deal with nested async calls to render().

Upvotes: 5

Views: 5756

Answers (2)

Alexandre Neuwald
Alexandre Neuwald

Reputation: 1

Have you try ejs.renderFile? its result is an HTML that you can send to the client.

Would be something like

res.send(await ejs.renderFile('./path/to/ejs/file.ejs', {}))

Upvotes: 0

Bill
Bill

Reputation: 25565

You can just pass a callback to res.render which will be called with the rendered string. This will be done async which is the right way to approach this since rendering may require a file read.

app.get('/', function(req, res){
  res.render('index', { title: 'Title' }, function(err, result) {
    res.render('index2', {foo: 'data'}, function (err, result2) {
      console.log('Render result:');
      console.log(result2);
      res.send(result2); // send rendered HTML back to client
    });
  });
});

If you don't like nested callbacks, I would suggest looking at an async library like the aptly names async. You can use the waterfall ( https://github.com/caolan/async#waterfall ) function to do this:

async.waterfall([
  function(done) {
    res.render('index', {title: 'Title'}, done);
  },

  function(result, done) {  // result is the result of the first render
    res.render( result, {foo: 'data'}, done);
  }
], function (err, result) {  // result is the result of the second render
  console.log(result);
  res.send(result);
});

Upvotes: 1

Related Questions