1
votes

I have a template that has data getting passed into it through the Iron Router params here, it might be obvious what the template is being designed to do:

lib/routes.js

// custom reset password page for child user
Router.route('/reset-password/child/:_id', {
    name: 'reset-child-password',
    template: 'childResetPassword',
    layoutTemplate: 'appLayout',
    data: function() {

        return Users.findOne({ _id: this.params._id });
    }
});

But, when I try to access this child user data in the template I get errors saying this.data is undefined. or cannot read property 'profile' of undefined. Here are my helpers and template use of the helper.

client/templates/childResetPassword.html

...

<h3>Reset Password for {{childFirstName}}</h3>
        <form id='childResetPassword'>
          <div class="form-group">
            <input type="password" name="new-child-password" class="form-control" value=''>
          </div>

...

client/templates/helpers/childResetPassword.js

Template.childResetPassword.helpers({
    childFirstName: function() {
        console.log("Template helpers:");
        console.log(this.data);
        return this.data.profile.firstname;
    }
});

Any thoughts on how to access the data-context passed with the iron router data callback? Am I using it incorrectly?

UPDATE (STILL NOT ANSWERED): I have verified that this particular user that I am passing into the template data-context is being found and that their profile is populated with a firstname property, and I'm still getting the same error.

Based on another question I found I tried this. I added a Template rendered callback function like this:

client/templates/helpers/childResetPassword.js

Template.childResetPassword.rendered = function() {
    console.log(this);

};

I do see this.data containing the correct user object in the browser console, but my this.data.profile.firstname still fails, yet again, with the same console output error. If there something I need to do between the template rendering and the template helper?? SO CONFUSED!!!

2

2 Answers

2
votes

You don't have to mention data ... you can just call this.profile.firstname. Your application already understands 'this' as the data object that is returned.

Template.childResetPassword.helpers({
    childFirstName: function() {
        return this.profile.firstname;
    }
});
1
votes

So, @Joos answer is not wrong, however after a lot more trial and error I found the solution for the meteor project I am working on.

My project (unbeknownst to me until I looked around more) has the meteor package autopublish removed. Therefore in order to access data in my collections I have to be subscribed to them. So the best place I put this subscription line is within my Router.route declaration for this template:

Router.route('/reset-password/child/:_id', {
    name: 'reset-child-password',
    template: 'childResetPassword',
    layoutTemplate: 'appLayout',
    waitOn: function() { // this is new new line/option i added to my route

        return Meteor.subscribe('users');
    },
    data: function() {

        if (this.ready()) {

            var childUser = Users.findOne({_id: this.params._id});
            if (childUser)
                return childUser;
            else
                console.error("Child User not found", childUser);
        }
        else {
            this.render("Loading");
        }
    }
});

So with that being said, if you still have autopublish package in your project and you intending to keep it, then @Joos answer is all you need to do.

However, if you DO intend to remove it, you need my router solution above, combined with making sure that you have published your users collection like this somewhere on the server:

server/publications.js

Meteor.publish("users", function () {
    return Meteor.users.find();
});