Maximus S
Maximus S

Reputation: 11125

Session object inside global template helpers

Session.set('coursesReady', false); on startup.

UPDATE:

I made it into a simpler problem. Consider the following code. Inside router.js

Router.route('/', function () {
  Meteor.subscribe("courses", function() {
    console.log("data ready")
    Session.set("coursesReady", true);
  });
}

and inside main template Main.js

  Template.Main.rendered = function() {
    if (Session.get('coursesReady')) {
      console.log("inject success");
      Meteor.typeahead.inject();
    }

The message "inject success" is not printed after "data ready" is printed. How come reactivity does not work here?

Upvotes: 0

Views: 151

Answers (2)

David Weldon
David Weldon

Reputation: 64342

Reactivity "didn't work" because rendered only executes once (it isn't reactive). You'd need to wrap your session checks inside of a template autorun in order for them to get reevaluated:

Template.Main.rendered = function() {
  this.autorun(function() {
    if (Session.get('coursesReady')) {
      console.log("inject success");
      Meteor.typeahead.inject();
    }
  });
};

Probably a better solution is to wait on the subscription if you want to ensure your data is loaded prior to rendering the template.

Router.route('/', {
  // this template will be rendered until the subscriptions are ready
  loadingTemplate: 'loading',

  waitOn: function () {
    // return one handle, a function, or an array
    return Meteor.subscribe('courses');
  },

  action: function () {
    this.render('Main');
  }
});

And now your rendered can just do this:

Template.Main.rendered = function() {
  Meteor.typeahead.inject();
};

Don't forget to add a loading template.

Upvotes: 1

wuguay
wuguay

Reputation: 11

To Solve Your Problem

Template.registerHelper("course_data", function() {
    console.log("course_data helper is called");    
    if (Session.get('coursesReady')) {
      var courses = Courses.find().fetch(); 
      var result = [ {                         **Changed**
          name: 'course-info1',
          valueKey: 'titleLong',
          local: function() {
            return Courses.find().fetch();
          },
          template: 'Course'
        }];
        Session.set('courseResult', result);   **New line**
        return Session.get('courseResult');    **New line**
      ,

Explanation

The answer is at the return of the helper function needs to have be associated with reactivity in order for Blaze, template renderer, to know when to rerender.

Non-reactive (Doesn't change in the DOM as values changes)

Template.Main.helpers({
    course_data: UI._globalHelpers.course_data    ** Not reactive
  });

Essentially: UI._globalHelpers.course_data returns an array of objects which is not reactive:

return [
        {
          name: 'course-info1',
          valueKey: 'titleLong',
          local: function() {
            return Courses.find().fetch();
          },
          template: 'Course'
        },

Reactive

From Meteor Documentation: http://docs.meteor.com/#/full/template_helpers

Template.myTemplate.helpers({
  foo: function () {
    return Session.get("foo");   ** Reactive
  }
});

Returning Session.get function to Blaze is reactive; thus, the template will change as the values changes.

Upvotes: 0

Related Questions