1

Having the strangest problem. I can't display the email property of an object. I'm using Mongoose/Express/Jade. I'm doing a:

User.find({ _id : { $in : req.project.subscribers } } , function (err, subs){...

Which works just fine and returns a list of my subscribers in the subs var that looks like so:

{ _id: 4f34832b9398bec847000002,
  email: 'steve@example.com',
  first_name: 'Steve',
  last_name: 'McQueen',
  status: 'active',
  username: 'steve',
  updated_at: Fri, 10 Feb 2012 02:38:35 GMT,
  created_at: Fri, 10 Feb 2012 02:38:35 GMT,
  role: 'subscriber' },

  { _id: 4f3484a9eceb82b548000002,
  email: 'paul@example.com',
  first_name: 'Paul',
  last_name: 'Stanley',
  status: 'active',
  username: 'paul',
  updated_at: Mon, 02 Apr 2012 15:09:56 GMT,
  created_at: Mon, 02 Apr 2012 15:09:56 GMT,
  role: 'subscriber' }

I then pass that to my jade view in a var called subscribers. All good to this point, the problem arises when I want to display the email property of each subscriber when I iterate over subscribers in my jade template. It's only a problem with email for some reason! It doesn't show anything for email, just blank.

ul
  each sub in subscribers
    li= sub.email

It works fine if I substitute ANY of the other properties in place of email. So the following displays perfectly fine:

ul
  each sub in subscribers
    li= sub.username

Please let me know if I can supply any more detail.

EDIT for Declan:

Doing the following:

ul
    each val, key in subscribers
     li #{key}: #{val}

Yields:

    0: { _id: 4f34832b9398bec847000002, email: 'foo', first_name: 'Steve', last_name: 
'McQueen', status: 'active', username: 'steve', updated_at: Fri, 10 Feb 2012 02:38:35 GMT, 
created_at: Fri, 10 Feb 2012 02:38:35 GMT, role: 'subscriber' }

1: { _id: 4f3484a9eceb82b548000002, email: 'foo', first_name: 'Paul', last_name: 'Stanley', 
status: 'active', username: 'paul', updated_at: Mon, 02 Apr 2012 16:05:51 GMT, created_at: 
Mon, 02 Apr 2012 16:05:51 GMT, role: 'subscriber' }
k00k
  • 17,314
  • 13
  • 59
  • 86
  • If just for testing, you add the loop in your controller and you try to console.log every sub in it, what does it show? is your property showing in it? – Tommy B. Apr 02 '12 at 15:37
  • Yes, it's showing, that's where I copy and pasted the overall objects from. – k00k Apr 02 '12 at 15:49
  • I'm wondering if jade is having issues with the special characters inside emails. Have you tried removing the @ and the . and testing if they are causing the issues? – Declan Cook Apr 02 '12 at 15:52
  • @DeclanCook Good thought, but no go. I set all email account values to foo and the problem persists. – k00k Apr 02 '12 at 15:55
  • Very odd, have you tired using the notation: each val, key in obj li #{key}: #{val} – Declan Cook Apr 02 '12 at 15:57
  • @DeclanCook See the original post, i've added an edit for you. Now I'm wondering if it's the way the object is set up. – k00k Apr 02 '12 at 16:14
  • @DeclanCook and as I would (or wouldn't) expect, #{key}: #{val.username} works fine and #{key}: #{val.email} doesn't :( – k00k Apr 02 '12 at 16:16
  • Yes, that's the markup. So subscribers consists of 2 records. Each of those records has the key value pairs (id, email, first_name, etc) – k00k Apr 02 '12 at 16:20

3 Answers3

5

I'm answering my own question because it ended up being something stupid and obvious (usually is, isn't it?).

When using mongoose and a property doesn't show up, be sure that you have that property defined in your mongoose schema. Somehow, I overlooked the email field when I created my schema and it just wasn't defined. Even though it was in the actual record in the DB, mongoose doesn't care and will only show you what you've defined for the object/schema.

Thanks to everyone for your efforts, if nothing else, you helped me get to my answer.

k00k
  • 17,314
  • 13
  • 59
  • 86
1

posting as an answer to allow for better code formatting.

I have just got home and thrown together a test app to see if I can duplicate your error. So far I haven't been able to. Here are my files

Note: I am not using a database for testing so the issue could be how you get the data from the database into the template:

index.jade

ul
  each sub in subscribers
    li= sub.email

routes/index.js

exports.index = function(req, res){
  res.render('index', { subscribers: [{ "_id": "4f34832b9398bec847000002",  "email": "steve@example.com",  "first_name": "Steve",  "last_name": "McQueen",  "status": "active",  "username": "steve",  "updated_at": "Fri, 10 Feb 2012 02:38:35 GMT",  "created_at": "Fri, 10 Feb 2012 02:38:35 GMT",  "role": "subscriber" },  { "_id": "4f3484a9eceb82b548000002",  "email": "paul@example.com",  "first_name": "Paul",  "last_name": "Stanley",  "status": "active",  "username": "paul",  "updated_at": "Mon, 02 Apr 2012 15:09:56 GMT",  "created_at": "Mon, 02 Apr 2012 15:09:56 GMT",  "role": "subscriber" }] })
};

app.js

var express = require('express')
  , routes = require('./routes');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

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

app.listen(8000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

Could you post your routes / app.get function will all the database handling code as well?

Declan Cook
  • 6,066
  • 2
  • 35
  • 52
  • I just console logged the result from the db and as expected, all properties looked good, including email. However, I then iterated over all properties within each record and console logged the key:value pairs and everything showed up EXCEPT email. Here's a pastie of my route: http://pastie.org/3722045 – k00k Apr 03 '12 at 17:27
0

The jade looks right to me, perhaps it's something in your request handler with how you're adding it to the view to be rendered. This simple example works:

server side request handler...

app.get('/', function(req, res) {
    var users = [{
        _id: '4f34832b9398bec847000002',
        email: 'steve@example.com',
        first_name: 'Steve',
        last_name: 'McQueen',
        status: 'active',
        username: 'steve',
        updated_at: "Fri, 10 Feb 2012 02:38:35 GMT",
        created_at: "Fri, 10 Feb 2012 02:38:35 GMT",
        role: 'subscriber'
    }, {
        _id: '4f3484a9eceb82b548000002',
        email: 'paul@example.com',
        first_name: 'Paul',
        last_name: 'Stanley',
        status: 'active',
        username: 'paul',
        updated_at: "Mon, 02 Apr 2012 15:09:56 GMT",
        created_at: "Mon, 02 Apr 2012 15:09:56 GMT",
        role: 'subscriber'
    }];
    res.render('index.jade', {subscribers : users });
});

contents of index.jade...

html
    body
        ul
            each sub in subscribers
                li= sub.email

that outputs...

<html>
    <body>
        <ul>
            <li>steve@example.com</li>
            <li>paul@example.com</li>
        </ul>
    </body>
</html>
Brad Harris
  • 1,520
  • 9
  • 12
  • Thanks for testing that. I think it might have to do with how Mongoose is returning the object. I don't think it's coming back as an actual array. When I console.log the result (subs) from Mongoose, I only see 2 comma separated objects like I show in the original post. Not sure that's right. – k00k Apr 02 '12 at 17:32
  • @k00k, it is right. When you console.log an array it does a toString which returns a comma delimited list of the array values. – Prestaul Apr 02 '12 at 18:35