GMeister
GMeister

Reputation: 341

Command-line jade "Cannot read property"

Running through this useful walkthrough for Node.js authentication with Passport, but utilising Jade templating rather than ejs. When actually running the app, the correct values are displayed in the HTML, but it annoys me that command-line jade complains. Any ideas why?

Here is the calling code:

exports.myAccount = function (req, res) {
    res.render('myAccount', {
        title: 'Welcome back.',
        user: req.user
    })
};

... and a snippet of the Jade file (myAccount.jade) :

div.row
    div.col-sm-6
        div.well
            h3
                span(class="fa fa-user")
                | Local
            p
                strong id
                | : #{user._id}
                br
                strong Username
                | : #{user.local.username}

Finally, the error when running Jade is:

TypeError: myAccount.jade:22
    20|                         p
    21|                             strong id
  > 22|                             | : #{user._id}
    23|                             br
    24|                             strong Username
    25|                             | : #{user.local.username}

Cannot read property '_id' of undefined
    at eval (eval at <anonymous> (..../lib/jade.js:172:8), <anonymous>:138:49)

As already mentioned, the values do actually render, so how do I get Jade to quit complaining??

adv-THANKS-ance

Upvotes: 0

Views: 1133

Answers (1)

Peter Lyons
Peter Lyons

Reputation: 146014

The short answer: provide some data on the command line so jade can properly render your string interpolation expressions such as #{user._id}.

jade --obj '{"user": {"_id": "42", "local": {"username": "bob"}}}' myAccount.jade

Explanation: Jade takes 2 things as input: some jade syntax plus some data. In your app, the data is provided by your code taking req.user, etc, so jade has what it needs to render the template to HTML. On the command line, there's no data there, so you have to provide it as I've done above.

Bonus Tip: There's more concise ways to express your template without so many pipes:

div.row
  div.col-sm-6
    div.well
      h3
        span.fa.fa-user Local
      p
        strong= "id: #{user._id}"
        br
        strong= "Username: #{user.local.username}"

Upvotes: 1

Related Questions