I'm trying to do some DOM manipulation on every evaluation of a helper function, {{htmlMarkup}}
. The problem is that when the page loads the helper is triggered before the template has a DOM.
Template.myTemplate.helpers({
htmlMarkup:function(){
var tmpl = Template.instance();
tmpl.$('.code-container').empty();
Tracker.afterFlush(function(){
Prism.highlightElement(tmpl.$('.code-container')[0]);
});
return input.get();
}
});
I will get the error message Exception in template helper: Error: Can't use $ on template instance with no DOM
. I have tried to check if tmpl.firstNode
is undefined but it doesn't work. What is the best way to solve this?
I'm trying to do some DOM manipulation on every evaluation of a helper function, {{htmlMarkup}}
. The problem is that when the page loads the helper is triggered before the template has a DOM.
Template.myTemplate.helpers({
htmlMarkup:function(){
var tmpl = Template.instance();
tmpl.$('.code-container').empty();
Tracker.afterFlush(function(){
Prism.highlightElement(tmpl.$('.code-container')[0]);
});
return input.get();
}
});
I will get the error message Exception in template helper: Error: Can't use $ on template instance with no DOM
. I have tried to check if tmpl.firstNode
is undefined but it doesn't work. What is the best way to solve this?
2 Answers
Reset to default 13We may check if the template is rendered (and thus have a DOM) with the property tmpl.view.isRendered
like this:
var tmpl = Template.instance();
if(tmpl.view.isRendered){
//Do DOM manipulation
}
Try setting a property on the template instance when it's getting rendered, and check if it's true in your helper.
Template.myTemplate.onCreated(function(){
this.isRendered = false;
});
Template.myTemplate.onRendered(function(){
this.isRendered = true;
});
Template.myTemplate.helpers({
htmlMarkup:function(){
var tmpl = Template.instance();
if(!tmpl.isRendered){
return input.get();
}
tmpl.$('.code-container').empty();
//
Tracker.afterFlush(function(){
Prism.highlightElement(tmpl.$('.code-container')[0]);
});
//
return input.get();
}
});
Depending on what you're trying to do, you could also use a Tracker.autorun
inside your Template.onRendered
handler to execute arbitrary code AFTER every input is detected.
Template.myTemplate.onCreated(function(){
this.input = new ReactiveVar("");
});
Template.myTemplate.onRendered(function(){
this.autorun(function(){
var input = this.input.get();
//
this.$(".code-container").empty();
//
Tracker.afterFlush(function(){
Prism.highlightElement(this.$(".code-container")[0]);
});
});
});
Template.myTemplate.events({
"input textarea": function(event, template){
template.input.set(template.$("textarea").val());
}
});