Meteor - Understanding template 'rendered' calls - meteor

I'm a bit of a newb in Meteor so this is possibly a trivial question for you Meteor masters out there.
I use a template which has a couple of child templates:
<template name="parent">
{{> child1}}
{{> child2}}
</template>
I noticed that parent.rendered and child1.rendered functions are invoked when reactive data under child2 changes.
My understanding of meteor docs is that only child2.rendered should be called. So, what I am seeing should not happen, yet for a reason which is beyond me, it does.
To rule out any noise, I gutted the child1 template (to contain only an empty div). Still, its rendered function is called.
Can anyone provide insight?

As of Meteor 0.7.0.1, the parent template will be re-rendered but the sibling child templates will not.
Here is a simple example Meteor app that shows this in action:
https://github.com/alanning/meteor-subtemplate-isolate-test
Keep in mind that Meteor UI is getting a drastic overhaul before Meteor 1.0 lands so a lot of things may change with respect to how templating works.

Just hypothesizing here, but I think the entire page rerenders when any reactive data changes. For example, if you were to have data in Session.get('test') and the only time the value of that is inserted into the DOM is in child2, I believe the entire page still rerenders.

Related

Mysterious hidden 'Reset your password' modal just under the body tag in Meteor

I use accounts-password in my meteor web-app, but only on two pages, where I include the usual {{> loginButtons }} code.
But a permanent hidden (display: none) modal with a title of 'Reset your Password' appears in the source just below the body tag, on every page. In other words it's in my layout, as a permanent part of my single page app, and I didn't put it there. It's appeared by itself, above the first piece of code in my layout, right below the <body> tag.
If I change the css display attribute to 'block', this is what appears:
No code of mine includes this modal, so I have no idea why it's there, and I would like to remove it, if possible.
As stated above, I do use accounts-password on a couple of pages, but so far I have used all the defaults, I haven't tailored the package in any way.
Can anybody shed any light on this?
This modal is declared in the accounts-ui-unstyled package which is a dependance of accounts-ui you're probably using.
Packages have the ability to declare global scoped templates and might include them on your behalf or when including a package-declared template such as {{> loginButtons}}, it's not a bug, it's a feature :)
I would recommend you leave the modal as it is, after all it's hidden by CSS and won't interfere with your normal app flow.
You may want to use another user accounts UI package such as useraccounts.
You could also come up with your own accounts-ui behavior, drop the standard package and no longer use {{> loginButtons}}, but think twice : is it worth the trade ?

Meteor load order running counter to documentation and other anamolies. Full example included

I still can't quite get Meteor's load order fully under control. I use a lot of 3rd-party scripts when using Bootstrap templates with animations and a lot of these scripts break because they are created with the traditional load order in mind for DOM nodes.
Meteor does not follow this traditional load order, so a lot of times DOM nodes aren't ready when the scripts fire.
I made a simple Meteor app that console logs a message each time a script inside of a particular folder or template.rendered callback is loaded.
https://github.com/fuzzybabybunny/meteor-load-order-test
You can see it deployed here (open up Chrome Console)
http://load-order-test.meteor.com/
There are a few strange things going on.
main.js and main.html are actually loaded very soon, counter to what the documentation says: http://docs.meteor.com/#/full/structuringyourapp
all the DOM nodes are actually created earlier than expected
with six templates that still have yet to have their .rendered() callbacks fired, the max number of DOM nodes has already been reached. We should expect more DOM nodes to be added with each .rendered() callback being fired.
Can someone help explain why I'm seeing these strange things?
Also, is there a surefire way to only run a script once all DOM nodes have been created? Currently it seems like using jQuery to append <script> tags somewhere on the DOM inside of Template.Layout.rendered would be the most foolproof.
Template.Layout.rendered = function(){
console.log('layout template rendered and the number of DOM nodes is ' + document.getElementsByTagName('*').length);
$('head').append('<script src="/javascript/domCompleteScript.js"></script>');
};
Per the documentation, slightly further down the page:
client/lib/ # code for the client to be loaded first
This folder is for compatibility JavaScript libraries that rely on variables declared with var at the top level being exported as globals. Files in this directory are executed without being wrapped in a new variable scope. These files are executed before other client-side JavaScript files.
I would try putting the 3rd-party scripts into the following places, just to see what works best:
client/lib
client/compatibility
lib

Meteor's iron:router isn't doing {{renderRouter}} as expected or documented

I've got a very simple template problem going on that appears to be similar to this guy's problem, though I've tried to build a simple example to demonstrate the problem and hopefully have someone explain to me how to fix or work around it.
Although as I'm doing some online research, it may be that the official documentation is out of date with the code. The reason I haven't bought into accepting that just yet is that the problem seems to have existed for a while, the dates on such articles in forums appears to be fairly old, and there's talk of it being fixed. There's also talk the feature is gone. What's the new way, if there is one?
I'm using Meteor 0.9.0.1 with iron:router 0.9.1. Specifically, I set up my project like this:
$ meteor create ironTest
$ cd ironTest
$ meteor add iron:router
$ meteor
Pointing my browser at http://localhost:3000/ as instructed, shows the default project. So far so good.
Now make ironTest.html contain this:
<body>
<h1>Before</h1>
{{renderRouter}}
<h2>Afterward</h2>
</body>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
Make ironTest.js contain this:
Router.configure({
autoRender: true // we will experiment with this Boolean shortly
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
If you go to the routes http://localhost:3000/hello and http://localhost:3000/goodbye, you'll see the templates correctly render as expected and documented, appended to the <body> element, so it appears after the <h2> element.
According to the current documentation for iron:router, one should be able to set the autoRender property to false, and the template should no longer be appended to the <body> element, but rather be injected where the Handlebars (okay, Spacebars) element {{renderRouter}} is, that is, between the <h1> and <h2> elements.
When I try this, visually it doesn't do anything. Opening a JavaScript Console to look at errors shows none. Although, by deliberately going to an invalid route it will show a missing template router exception, showing the routing code is indeed working.
Does anyone know how to coerce the code above into working?
For the curious, I've got a working simplistic equivalent that might be of use to others working this problem.
This new ironTest.html uses a template (for a layout) with no <body>:
<template name="main">
<h1>Before</h1>
{{> yield}}
<h2>Afterward</h2>
</template>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
This ironTest.js instead uses a layout:
Router.configure({
layoutTemplate : 'main'
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
It's worth an aside that this solution doesn't work for me, as I don't want a global layout, and have concern that riddling layouts in the route themselves is a tighter coupling than desired for my purposes.
I'm currently looking for a way to dump debugging log information from the Router as it performs transitions, but that's another story.

What is Template.myTemplate.helpers(helpers) for and why should I use it?

In Meteor, if the below is my HTML,
<template name="myTemplate">
The value is {{value}}
</template>
I can define the value in two ways
Template.myTemplate.helpers
value: ->
'insideHelper1'
Template.myTemplate.value =
'outsideHelper1'
The first way is using helpers as documented here (http://docs.meteor.com/#template_helpers) whereas the second way is using the Live Template examples as defined here (http://docs.meteor.com/#livehtmltemplates)
Just wondering, what is the difference between the two and when should I use one over the other?
They're exactly the same.
If you use .helpers, it actually just adds it to Template..
It depends on your coding style. You may prefer to use .helpers since it makes cleaner code if you have many helpers on the same template.
One small technically way they're different is Template.helpers adds the helpers to your Meteor app when your Meteor app starts up, whereas using the Template.helpername adds it before. So if you need to overwrite any helpers, you could use the .helpers method. The one that runs last will have the active helper.

With Meteor, why calling MyCollection.findOne affects other template functions?

I am using findOne just to fetch one certain element for my collection.
However, when I do that, all my template functions containing those collections are re-run and the content refreshed. The content is similar, the problem is I am applying styles to some of those elements, and these updates just reset everything as well. More importantly: those refreshes are completely useless.
For example, I have this template:
Template.content.cars = function () {
alert("I AM RERUN!");
return Cars.find();
};
And in another function, I am doing this:
Cars.findOne({ _id: Session.get('current_car') }, {});
Why would be the first template re-run? Am I doing something wrong?
I'm not sure why your first template would be re-run: are you sure something else isn't going on?
But as a general non-answer to your question: you should expect that a template which depends on the entirety of a collection will be re-run many times (for instance as the data loads incrementally when the page first renders). With meteor you need to write your HTML/CSS in such a way that this re-rendering won't cause problems.
Without knowing more about your problem I can't really say more than that.

Resources