Search code examples
node.jsmongodbmongoosedust.jskraken.js

node, mongoose, dust - Printing Query Results using Dust


I am rebuilding an existing project using KrakenJS as a way to learn how to use node to build applications. By following this tutorial I was able to understand a lot of the concepts.

However, I am still struggling to understand how Dust works, and I think that my problem lies there. I am very familiar with Rails, and so I understand the MVC model. However I don't know how Dust works with the rest of the stack.

In my the schema for my User model, I have the following code:

userSchema.methods.messages = function() {
    var user = this;
    var messages = MessageModel.find({ref: user.ref}, function(err, messages) {
      if(err) {
        console.log(err);
        return err;
      }
      else {
        console.log(messages);
        return messages;
      }
    });
  };

This works, because I can log to the console and get the correct output.

I am trying to print these messages using Dust on the front end, but to no avail.

Here is my code:

You are <strong>{user.name}</strong> and your role is <strong>{user.role}</strong><br />
Your ref number is <strong>{user.ref}</strong>.
{#user.messages}
   {.body} <br /> 
{/user.messages}

user.name, user.role and user.ref work just fine. I am unable to print the messages.

Here is what should be contained in user.messages.

[ { from: '+0000000000',
    body: 'test',
    ref: 123,
    _id: 5342bf04ce29220200a3cb8e,
    __v: 0 },
  { from: '+0000000000',
    body: 'second message',
    ref: 123,
    _id: 5342cb4604f6f2020068a9b8,
    __v: 0 } ]

Solution

  • The problem is that

    var messages
    

    is not going to be populated with the actual messages, it will always be "undefined". Since Node works asynchronously it doesn't wait for your query to finish.

    To solve this problem you need to add a callback to your function, like this:

    userSchema.methods.messages = function(callback) {
      var user = this;
      var messages = MessageModel.find({ref: user.ref}, callback);
    }
    

    And then in your controller/route you do the following:

    server.get('/', function(req, res, next) {
      User.messages(function(err, messages) {
        if(err) return next(err);
        res.render('template', { messages: messages });
      }
    }
    

    Instead of using "user.messages" in your templates, just use "messages".