title: Meteor: How to get Reactive Parent/Child dependency templates for Object attributes
body: <p>I'm working on a reactive dependence tree on Meteor (with Blaze), but I didn't found the best way to do it.</p>
  
  <p><strong>First, the problem</strong></p>
  
  <p>On this example I have container who set an <code>item</code> Object, who have an attribute <code>elements</code> (Array).</p>
  
  <p>The <code>elements</code> attribute is loop, and a child template is loaded for every instance of it.</p>
  
  <p>The element can be update on the child template, but the update isn't propagate to the container.</p>
  
  <p>Also, I added an <code>Add</code> button to update the <code>item</code> ReactiveVar (from the <code>container</code>). Each field rendering is updated after <code>item</code> is updated on container, so the object as been updated but not re-rendered.</p>
  
  <p><strong>HTML</strong></p>
  
  <pre><code>&lt;template name="container"&gt;
    {{#let item=getItem}}
      &lt;h1&gt;Update {{item._id}}&lt;/h1&gt;
      {{#each element in item.elements}}
        &lt;div&gt;
          {{&gt; elementForm element}}
          &lt;small&gt;{{element.name}}&lt;/small&gt;
        &lt;/div&gt;
      {{/each}}
    {{/let}}
    &lt;button name="add"&gt;Add&lt;/button&gt;
  &lt;/template&gt;
  
  
  &lt;template name="elementForm"&gt;
    {{#let el=getEl}}
      &lt;input value="{{el.name}}"/&gt;
    {{/let}}
  &lt;/template&gt;
  </code></pre>
  
  <p><strong>Parent Template</strong></p>
  
  <pre><code>Template.container.onCreated(function onContainerCreated() {
    // From data
    let item = {
      _id: '123abc',
      elements: [
        {name: "El #1"},
        {name: "El #2"},
        {name: "El #3"},
      ]
    }
    // Create master ReactiveVar
    this.item = new ReactiveVar(item);
  });
  
  Template.container.helpers({
    getItem() {
      return Template.instance().item.get();
    },
  });
  Template.container.events({
    // Add a new element (Will refresh all elements render)
    'click button[name="add"]'(e) {
      let instance = Template.instance()
      let item = instance.item.get()
      item.elements.push({name: "new El"})
      instance.item.set(item)
    },
  })
  </code></pre>
  
  <p><strong>Child template</strong></p>
  
  <pre><code>/* Element */
  Template.elementForm.onCreated(function onElementCreated() {
    this.el = new ReactiveVar(this.data)
  });
  Template.elementForm.helpers({
    getEl() {
      return Template.instance().el.get()
    }
  })
  Template.elementForm.events({
    'change input'(e) {
      let instance = Template.instance()
      let el = instance.el.get()
      el.name = e.currentTarget.value
      instance.el.set(el)
    }
  })
  </code></pre>
  
  <p><strong>Preview</strong></p>
  
  <p>As meteor can't be integrate on Embed code, I make some images.</p>
  
  <p>Default page</p>
  
  <p><a href="https://i.stack.imgur.com/2ctqt.png" rel="nofollow"><img src="https://i.stack.imgur.com/2ctqt.png" alt="enter image description here"></a></p>
  
  <p>Update input didn't affect container render</p>
  
  <p><a href="https://i.stack.imgur.com/7eeRB.png" rel="nofollow"><img src="https://i.stack.imgur.com/7eeRB.png" alt="enter image description here"></a></p>
  
  <p>Add a new item, will re render all the container and get new values</p>
  
  <p><a href="https://i.stack.imgur.com/fEzLy.png" rel="nofollow"><img src="https://i.stack.imgur.com/fEzLy.png" alt="enter image description here"></a></p>
  
  <p><strong>Solution 1 ?</strong> Send <code>item</code> ReactiveVar to the child</p>
  
  <p>I know than sending the entire ReactiveVar to a child can be a solution to use the <code>.set()</code> method on the child. </p>
  
  <p>But if I use this hack, I will have to send the entire <code>item</code> to each <code>elementForm</code> (not the best)</p>
  
  <p><strong>Exemple</strong></p>
  
  <pre><code>/* Html */
  &lt;Template name="parentTemplate"&gt;
    &lt;small&gt;{{getFoo}}&lt;/small&gt;
    {{&gt; childTemplate getItem}}
  &lt;/Template&gt;
  &lt;Template name="childTemplate"&gt;
    &lt;input value="{{getFoo}}" /&gt;
  &lt;/Template&gt;
  
  /* Parent */
  Template.parentTemplate.onCreated(function onParentCreated() {
    this.item = new ReactiveVar({ foo: bar})
  });
  Template.parentTemplate.helpers({
    getFoo() {
      return Template.instance().item.get().foo    
    },
    getItem() {
      return Template.instance().item // Send reactive var, net value (.get)
    }
  })
  /* Child */
  Template.childTemplate.onCreated(function onChildCreated() {
    this.item = this.data.item // Use Parent Reactive var
  });
  Template.childTemplate.helpers({
    getFoo() {
      return Template.instance().item.get().foo    
    },
  })
   Template.childTemplate.events({
    'change input'(e) {
      let item = Template.instance().item.get()   
      item.foo = e.currentTarget.value
      Template.instance().item.set(item) // Will update parent   
    },
  })
  </code></pre>
  
  <p><strong>Solution 2 ?</strong> Callback</p>
  
  <p>An other solution is to send to the child template, in addition to element data, a callback for each action (like change) to inform the parent template to update the master ReactiveVar for a specific element.</p>
  
  <p><strong>Example</strong></p>
  
  <pre><code>/* Html */
  &lt;Template name="parentTemplate"&gt;
    &lt;small&gt;{{getFoo}}&lt;/small&gt;
    {{&gt; childTemplate getData}}
  &lt;/Template&gt;
  &lt;Template name="childTemplate"&gt;
    &lt;input value="{{getFoo}}" /&gt;
  &lt;/Template&gt;
  
  /* Parent */
  Template.parentTemplate.onCreated(function onParentCreated() {
    this.item = new ReactiveVar({ foo: bar})
  });
  Template.parentTemplate.helpers({
    getFoo() {
      return Template.instance().item.get().foo    
    },
    getData() {
      let instance = Template.instance()
      return {
        item: instance.item.get(),
        onChange: function(val) {
          // Update item here
          let item = instance.item.get()
          item.foo = val
          instance.item.set(item)
        }
      }
    }
  })
  /* Child */
  Template.childTemplate.onCreated(function onChildCreated() {
  });
  Template.childTemplate.helpers({
    getFoo() {
      return Template.instance().data.item.foo    
    },
  })
   Template.childTemplate.events({
    'change input'(e) {
      // Call parent callback
      Template.instance().data.onChange(e.currentTarget.value)  
    },
  })
  </code></pre>
  
  <p><strong>Final Question</strong></p>
  
  <p>What's the best way to handle Parent/Child Template to handle a list of element from a item object ?</p>