Search code examples
meteorreactive-programmingmeteor-autoformmeteor-helper

Meteor template not updating when template helper re-runs


I am trying to make a custom form wizard that will contain different autoform steps based on certain conditions. A simplified meteorPad example is linked below. When the reactive data source(session variable) changes the reactive computation(template helper) runs, confirmed by console output. The template, however, is not updated and still has the same number of steps. Is there something I need to do to make the template update correctly? Thanks! http://meteorpad.com/pad/cPWShRiTKYpBaMahn/Leaderboard

html

<body>
  {{> basicWizard}}
  {{> changeSteps}}
</body>

<template name="basicWizard">
<!--shouldn't the steps variable update when the helper runs?-->
  {{> wizard id="basic-wizard" steps=steps}}
</template>

<template name="changeSteps">
 <button id="changeStepsButton"> change number of Steps </button>
</template>

client code

Session.set('twoSteps', false);

information = new SimpleSchema({
  password: {
    type: String,
    label: 'password',
  },
});
confirm = new SimpleSchema({
  userName: {
    type: String,
    label: 'blah',
  },
});

Template.basicWizard.helpers({
    steps: function() {
      var ret = [];
      if (Session.get("twoSteps")) {
      ret[ret.length] = 
        {
          id: 'information',
          title: 'Information',
          schema: information,
        }
      }
      ret[ret.length] = 
        {
          id: 'confirm',
          title: 'Confirm',
          schema: confirm  ,
        }
      console.log("num steps: " + ret.length)
      return ret;
    }
  });

Template.changeSteps.events({
  "click #changeStepsButton": function (event) {
    Session.set('twoSteps', !Session.get("twoSteps")); 
  }, 
})

Solution

  • Looks like the hassle is that the Wizard doesn't handle steps reactively. I suspect it's the following code in the Wizard package:

    The "new WizardConstructor" call below is where I think the reactivity is breaking: Template.wizard.created = function() { var id = this.data.id || defaultId; this.wizard = wizardsById[id] = new WizardConstructor(this.data); };

    Somewhere in wizard constructor it does this call: _.each(this.steps, function(step) { self._initStep(step); });

    But I don't think Meteor knows to recreate the template when "this.data" changes. Technically the Wizard is not binding to the "steps" which is why it's not working. I suspect the creator of the wizard package did not intend for it to be used in this way.