Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

express view cache acting funny

I'm running into some funny stuff with the view cache in express/Jade. The controller fetches an article from MongoDB via Mongoose and hands it to the res.render function. However, after running for a couple of minutes Express starts serving the same compiled template for all requests to that route. This even happens to shared .jade includes that are used in various templates.

The database is fetching the correct articles and it doesn't matter if I pass some random strings to the template, I always get the same output.

This is the controller function:

exports.show = function(req, res) {
  var articleId;
  articleId = req.params.id;
  Article.findOne({
    _id: articleId
  }).populate('author').exec(function(err, article) {
    if (err) {
      console.log(err);
    } else {
      res.render('articles/show', {
        article: article,
        articleId: article.id
      });
    }
  });
};

And that's the route:

app.get('/articles/:id', articles.show);

The same things happen whether I'm running in production or development mode.

Has anyone run into this kind of toruble with Express/Jade?

like image 533
Ólafur Nielsen Avatar asked Jun 04 '13 16:06

Ólafur Nielsen


2 Answers

Edit: Notice that express sets view cache enabled for production: see express docs

view cache Enables view template compilation caching, enabled in production by default

Try adding this line in your app config section:

app.disable('view cache');

Also, try adding cache-control headers

res.setHeader('Cache-Control', 'no-cache');
res.render('articles/show', {
...

From w3.org docs:

Cahce-Control

The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain. The directives specify behavior intended to prevent caches from adversely interfering with the request or response. These directives typically override the default caching algorithms. Cache directives are unidirectional in that the presence of a directive in a request does not imply that the same directive is to be given in the response.

If you need a more advanced control, consider other fields like max-age, this question is also a good resource, you'll see that different browsers may implement this rfc slightly different.

like image 56
alfonsodev Avatar answered Oct 23 '22 19:10

alfonsodev


TL;DR: try

let articleId;

instead of

var articleId;

I'm just another newbro to Node.js, but I've just solved the same issue by substituting "var" keyword for "let". The thing is that "var" creates a variable scoped by a function, while "let" – a scoped to the current block one. It is re-created every time the block is executed, which is important due to asynchronous nature of Node.js.

like image 34
Fractal Multiversity Avatar answered Oct 23 '22 18:10

Fractal Multiversity