Changing CSS in onRendered for Subscribed data

Hi!

I have an application that should highlight some certain HTML fields red if they’re “erroneous”. These fields coincide with documents from a subscription. I figured it’d make most sense to apply this changing of CSS on the fields in onRendered (as it’s a simple DOM manipulation that’s done once the template has already been created). I think the problem with this is that onRendered wouldn’t necessarily have access to my subscribed document in MiniMongo and thus wouldn’t be able to apply the css.

Here’s some stuff I’ve been trying. The template example is called “Object” and I’ll be subscribing and working on “Objects”

import { Objects } from …

//Simple onCreated where I’m subscribing to Objects
Template.Object.onCreated(function () {
var self = this;
self.autorun(function () {
self.objectSubscription = Meteor.subscribe(‘Object’, {
onReady: function () {
},
});
}
});

//onRendered where I try to change the css of an Object in MiniMongo
Template.Object.onRendered(function () {
const obj = Objects.findOne({someWhereClause});
if (obj.isErroneous) {
$(’#objID’).addClass(‘error’);
}
}

The problem is that onRendered does not see anything in my MiniMongo collection and thus cannot find an Object and set its style. I’m confused as to how this is possible though, because the subscription already gets completed in onCreated. I’m using the MiniMongo explorer and not seeing anything in my Objects explorer after onCreated. However, I’m seeing it if I subscribe in onRendered (but I can’t do this because it leads to redundant subscriptions and is not an appropriate place to put it)

It looks like I can solve this using a Helper. So in HTML I’d have something like

{{object}}

and then my helper would be

isErroneus(object) {
return object.isErroneous ? ‘error’ : ‘’;
}

Is this the preferred pattern of how to solve something like this in Meteor? Why wouldn’t onRendered worl? Also, is there any way to avoid passing ‘object’ to my Helper; i.e. is there any way to call ‘this’ as the helper should refer to an instance of the Template, right?

The reason you can’t get reactive behaviour in onRendered is that, like onCreated, it’s not reactive by default. However, template helpers do provide a reactive context in which changes to MongoDB collections will be seen and acted upon.

This is a (very simplified) form of best practice and will hopefully give you some pointers:

import { Objects } from …

//Simple onCreated where I’m subscribing to Objects
Template.Object.onCreated(function () {
  this.subscribe('Object');
});

//helper where I change the css class of an Object
Template.Object.helpers({
  objectClass() {
    const obj = Objects.findOne({someWhereClause});
    if (obj.isErroneous) {
      return 'error';
    } else {
      return 'normal';
    }
  }
}

and the HTML:

<template name="Object">
  <div class="{{ objectClass }}">some content</div>
</template>
1 Like

Ah! Thanks for clarifying robfallows. I’m using helpers now and it seems much more intuitive. Thanks

1 Like