So revisiting this…
This aspect of Blaze has always flummoxed me! It turns out it was my use of Template.subscriptionsReady()
that was my real problem, <template>.onRendered
works as advertised.
@jamgold came up with a hacky workaround that I did not really grok on first read:
Same problem. Your Template.productDetail.onRendered fires when the template gets rendered, which is most likely before Template.subscriptionsReady
In the part where you have …display product… you could just call another template and attach the onRendered to that.
So I will be very pedantic. What he is saying is this:
@jamgold’s Hacky workaround
foo.html
:
<template name="parent">
{{#if Template.subscriptionsReady}}
<div id="firstDiv"></div>
{{> childHack}}
{{/if}}
</template>
<!-- childHack template can be empty -->
<template name="childHack"></template>
foo.js
:
Template.parent.onRendered(function parentOnRendered() {
console.log($('#firstDiv').length); // What?? it is 0, nothing found!!
// Nothing is found because Template.subscriptionsReady() is false,
// parent template is successfully rendered with no HTML.
});
Template.childHack.onRendered(function childHackOnRendered() {
console.log($('#firstDiv').length); // Hey it is 1, gotcha!
// this template will only be rendered when Template.subscriptionsReady()
// is true & the parent template completed rendering its HTML with data
});
Even if this is hacky, it is relatively simple & elegant for handling the cases when you use Template.subscriptionsReady()
.
THANKS @jamgold!
========== EDIT ==========
Right after posting this I had another thought. And fell upon @mrzafod’s solution. Without the childHack
template you can do this:
@mrzafod’s elegant solution
foo.js
:
Template.parent.onRendered(function parentOnRendered() {
console.log('found1?: ', $('#firstDiv').length); // 0, nothing found
// Nothing is found because Template.subscriptionsReady() is false,
// parent template is successfully rendered with no HTML.
let initialized = false;
template.autorun( () => {
if(!initialized && template.subscriptionsReady()) {
// Subscriptions are now ready, the template is rendering
console.log('found2?: ', $('#userprofile-modal').length); // 0, nothing found
// Nothing is found, because we are still rendering templates
initialized = true;
Tracker.afterFlush(() => {
// Reactivity computations have finished
console.log('found3?: ', $('#userprofile-modal').length); // 1
// Now the DOM is populated with the template HTML
});
});
});
Thanks @mrzafod !!