Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content wrapped in currentUser re-rendering when user updated

Tags:

meteor

I'm using Meteor and having an issue where my content is being re-rendered when I don't want it to.

I have my main content wrapped in a currentUser if statement which I feel is fairly standard.

{{#if currentUser}}
  {{> content}}
{{/if}}

The problem with this is my content template is being re-rendered when I update my user object. Is there any way around this? I don't reference users anywhere inside the content template.

Thank you!

Here's a sample app to replicate my problem:

HTML

<head>
  <title>Render Test</title>
</head>

<body>
  {{loginButtons}}

  {{> userUpdate}}

  {{#if currentUser}}
    {{> content}}
  {{/if}}
</body>

<template name="userUpdate">
  <p>
    <input id="updateUser" type="button" value="Update User Value" />
    User last update: <span id="lastUpdated">{{lastUpdated}}</span>
  </p>
</template>

<template name="content">
  <p>Render count: <span id="renderCount"></span></p>
</template>

JavaScript

if (Meteor.isClient) {
  Meteor.startup(function() {
    Session.set("contentRenderedCount", 0);
  });

  Template.content.rendered = function() {
    var renderCount = Session.get("contentRenderedCount") + 1;
    Session.set("contentRenderedCount", renderCount);
    document.getElementById("renderCount").innerText = renderCount;
  };

  Template.userUpdate.events = {
    "click #updateUser": function() {
      Meteor.users.update({_id: Meteor.userId()}, {$set: {lastActive: new Date()}});
    }
  };

  Template.userUpdate.lastUpdated = function() {
    return Meteor.user().lastActive;
  };

}

if (Meteor.isServer) {
  Meteor.users.allow({
    'update': function () {
      return true; 
    }
  });
}

Update: I should've explained this example a little. After creating a user, clicking the Update User Value button, causes the render count to increment. This is because it's wrapped in a {{#if currentUser}}. If this is if is removed, you'll notice the render count remains at 1.

Also, you'll need to add the accounts-ui and accounts-password packages to your project.

like image 346
Irving Avatar asked Feb 09 '13 01:02

Irving


1 Answers

Meteor will re-render any template containing reactive variables that are altered. In your case the {{currentUser}} is Meteor.user() which is an object containing the user's data. When you update the users profile, the object changes and it tells meteor to re-calculate everything reactive involving the object.

We could alter the reactivity a bit so it only reacts to changes in whether the user logs in/out and not anything within the object itself:

Meteor.autorun(function() {
    Session.set("meteor_loggedin",!!Meteor.user());
});

Handlebars.registerHelper('session',function(input){
    return Session.get(input);
});

Your html

{{#if session "meteor_loggedin"}}
    {{> content}}
{{/if}}    
like image 179
Tarang Avatar answered Nov 02 '22 20:11

Tarang