2

What could be wrong with passing the request object to the jade renderer?

This seem like a simple way to work. Especially as express.js already uses the request object as a vehicle from append data as the HTTP request makes its way to its middleware end point.

Therefore, instead of passing a custom data object to the jade rendered, could one just append data to the request allowing more logic to be handled from with in jade. For example:

app.get("/", function (req, res) {  
   res.render("index", req);
});

Are there consequences to doing such a technique? Could this be frown upon or admired? Could it expose to much to jade? Performance impact?

For example, here is some people wishing to send data already in the request to jade:

I am sure there are more related questions which could be solved by just sending the request. It's not suggested, why?

Community
  • 1
  • 1
Ross
  • 14,266
  • 12
  • 60
  • 91

2 Answers2

9

The design for how express handles locals seems to be "include what's needed." It just doesn't make any assumptions about what that is.

So, if in your case, you need a large part of properties that are attached to the request and don't want to have to "extract" them from it ("instead of passing a custom data object to the jade rendered"), then it should be fine.

However, the possible issue isn't really with whether you include it in locals, but whether you're using it as a crutch and over-complicating your views. You want to keep your views rather simple and only "just intelligent enough" to render what's needed.


Side note: I would recommend defining it so req or request is the local rather than its properties:

res.render("index", { req: req });

This offers at least these benefits:

  1. Since Express has 3 sources for locals it needs to merge (app.locals, res.locals, and locals passed to res.render()), this lets it be done after a single property rather than having to loop over everything in the request.

  2. Any methods are still attached to an instance rather than copied to a plain Object.

You could also attach it in a small middleware so it isn't route-specific:

app.use(function (req, res, next) {
    res.locals.req = req;
    next();
});
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
2

The biggest problem of doing res.render("index", req) is that most likely, the req object contains insufficient information to create the full response. You'd somehow would need a way to pull in more data from within the Jade template code, for which I wouldn't know any way of doing but using global variables, which would lead to a very strange architecture indeed. In general, it's best to have code you write assume the minium of how its used, including in what kind of environment its run. This applies to templates just as well.

Passing the entire req object as part of the variables you send to the jade template, i.e. res.render({req:req,data:someOtherData}) is problematic as well, because it makes the template dependent on the full request object. You can't reuse the template when - at some point - you want to use it outside of the context of an Express request. It's not hard to be more specific about what data you send to a template. But really, this principle applies to almost any code.

You mention as a potential benefit "allowing more logic to be handled from with in jade". I wonder how that's a benefit. Jade can do some logic, but to me, it feels like a rather constraint environment. It works well for the occasional loop or conditional, but not for anything else. The request handler is the ideal place to do the more advanced logic.

Myrne Stol
  • 11,222
  • 4
  • 40
  • 48
  • I wholly get your comments on the amount of information provided and dependancy. And these are most certainly principles that apply to almost any code. However, just because the route handler exists does not *always* mean it should be used to define logic. When the express app only provides a few routes (say two, three, maybe four) recreating the data could be considered *premature optimisation*. "I wonder how that's a benefit": **when** it allows for vastly more simpler, clearer and concise code as whole. The request the model, express the controller, jade the view. – Ross May 07 '13 at 18:04
  • Therefore not suggesting that this be best practice but that there may be cases where it is acceptable only if there are not security or performance issues (hence the question). – Ross May 07 '13 at 18:06
  • Ehm, the most specific you got with your question was "What could be wrong with passing the request object to the jade renderer?", and "It's not suggested, why?". Not "Am I gonna live if I do otherwise in cases where it doesn't make sense." Yes, you'll live. :) – Myrne Stol May 07 '13 at 18:16
  • :). Sorry for not being to specific. Was looking for a discussion and that's what I got. Thanks! Hopefully I am not living on the edge to much here. – Ross May 07 '13 at 18:19