0

I have an API .get call in Node.js that retrieves all of the Messages to a specific user.

.get(function(req, res) {

    console.log(req.session.username);

    Models.Message.find( { "to.username": req.session.username } ).exec(function (err, messages) {

        if (err)
            res.send(err);

        res.json(messages);

    });

These Messages are delivered via res.json(messages); over AJAX to a handlebars templating script.

function allTheDocs(resJSON) {

  var templateSource = $("#messagesTemplate").html();

  var template = Handlebars.compile(templateSource);

  var messagesHTML = template({messages: resJSON});

  $('#messages').html(messagesHTML);

}

In the script I would like to call a custom comparison helper, such that if a field:value of the MongoDB data === the session/local variable in node.js -> the templated HTML then renders.

Handlebars.registerHelper('ifEqual', function(v1, v2, options) {
  if (v1 === v2) {
    return options.fn(this);
  }
  return options.inverse(this);
});

How would I send either an express session variable (req.session.username) or a local variable (res.locals.username) along with the res.json(messages), to then specifically template the unread Messsages for the session user?

{{#each messages}}
    {{#ifEqual to.username req.session.username}}
        {{#if read.marked}
            <div class="unreadMessages">{{../message}}</div>
        {{else}
            <div class="readMessages">{{../message}}</div>
        {{/if}}
    {{/if}}
{{/each}}

Messages are marked unread in a MessageUserSchema that is an embedded array in each Message, so as to account for the option of being sent To any number of users (one to many).

{
    "_id" : ObjectId("53b203c2cc3060000000eadc"),
    "message" : "Here's a sample Message",
    "to" : [
        {
            "user" : ObjectId("53aada6f8b10eb0000ec8a90"),
            "username" : "username1",
            "updated" : ISODate("2014-07-01T05:46:22Z"),
            "_id" : ObjectId("53b24b2e35eaa0a4106ca21c"),
            "read" : {
                "marked" : false
            }
        }
    ]
}
Community
  • 1
  • 1
StackThis
  • 883
  • 3
  • 15
  • 45

1 Answers1

1

Ideally you should only pass one object into the view, thus the reason why these are normally called ViewModel. Express only accepts one json to be passed as the view model. You can add your info there:

Models.Message.find( { "to.username": req.session.username } ).exec(function (err, messages) {

    if (err)
        res.send(err);

    res.json({
         messages : messages,
         sessionUserName: req.session.username
      });

});

Then in your template:

{{#each messages.messages}}
    messages.sessionUserName
...
{{/each}}
fmsf
  • 36,317
  • 49
  • 147
  • 195
  • Thanks for this.. messages.sessionUserName doesn't render anything though.. console.log(messages.sessionUserName); after the res.json() logs undefined.. And testing the templating with {{#if messages.sessionUserName}}

    Hello World

    {{/if}} doesn't render.. Any other suggestions?
    – StackThis Jul 01 '14 at 19:09
  • given the code you have above this should work, unless req.session.username is undefined. Have you tried to output the entire object into the template to see what is there? – fmsf Jul 01 '14 at 22:16
  • Thanks for that.. Tested in the ajax log, and it was right there, and in the API too.. Realized it was the way I was calling it in the Handlebars script.. – StackThis Jul 01 '14 at 22:49
  • hey, asked this as a separate question because this post was really about express..this one https://stackoverflow.com/questions/24523697/handlebars-helper-to-compare-values-if-v1-v2-and-render-upper-level-scope is about the handlebars part, if you have a chance to take a look..thanks either way – StackThis Jul 02 '14 at 05:47
  • any thoughts on this one: https://stackoverflow.com/questions/24523697/handlebars-helper-to-compare-values-if-v1-v2-and-render-upper-level-scope thanks again – StackThis Jul 04 '14 at 03:19