Chanpory
Chanpory

Reputation: 3095

Meteor JS: How do I access the previous record in a collection?

I have a list of messages in a collection. When rendering each message in a collection, I'd like to compare the timestamps and userIds of the message to the previous message. However, I am not sure how to access the data to do the comparison. Any advice would be appreciated.

Here's are my templates:

<template name="messageList">
  <ul>
    {{#each messages}}
      {{>messageItem}}
    {{/each}}
  </ul>
</template>

<template name="messageItem">
  <li>
    <p class="{{nameVisibility}}">{{userName}}</p>
    <p>{{body}}</p>
  </li>
</template>

Here is my helpers file:

Template.messageItem.helpers({
  nameVisibility: function() {

    //Not sure how to query the previous message in relation to this one.
    previousMessage = Messages.findOne(...);
    if (this.userId != previousMessage.userId) {
      return false;
    else {
      return "hideName";
    }  
  }
});

Upvotes: 2

Views: 204

Answers (2)

Andrew Mao
Andrew Mao

Reputation: 36930

I disagree with the other answer in this post, which is horribly inefficient and requires iterating over the entire Messages collection an extra time.

I think the best way to do this would be with regular jQuery in the Template.messageItem.rendered callback. You can find the previous element, use UI.getElementData to find its data, and either remove or add the username as appropriate. On Meteor 0.8.0+ (Blaze rendering engine), your edits will stick. Something like this:

Template.messageItem.rendered = function() {
  // this.firstNode is the <li> tag; .prev() grabs its previous sibling
  prevMessage = $(this.firstNode).prev();
  prevData = UI.getElementData(prevMessage[0]); // but make sure prevMessage[0] exists
  if (prevData.userName === this.data.userName)
    this.$(".username").remove(); // Make sure you put the ".username" class on the prefix
}

Upvotes: 1

Geoffrey Booth
Geoffrey Booth

Reputation: 7366

Preprocess the array you’re looping over:

Template.messageList.helpers({
  messages: function() {
    var i, j, messages;
    messages = Messages.find({}).fetch(); // Replace `{}` with your query
    for (i = 0, j = ret.length; i < j; i++) {
      if (messages[i-i] != null && messages[i].userId == messages[i-1].userId)
        messages[i].nameVisibility = "hideName";
    }
    return messages;
  }
});

Upvotes: 1

Related Questions