Accessing #each data context in Template event


#1

Say I have this scenario:

template1.html

...
{{#each thing in things}}
    {{thing.name}}
    <button name="doThing">Do thing with thing id</button>
{{/each}}
...

template1.js

Template.template1.events({
    'click button'(event, instance) {
         // instance refers to the entire template here, not the context within the #each loop
    }
});

If I want to attach events to each button do something that uses the thing id, how do I get that context? I know I can create another template and attach event handlers on that, but it’s a bit tedious to create new templates for each time I want to iterate


Blaze template event unable to access data of #each in template?
#2

Switch your #each to something like:

...
{{#each things}}
  {{name}}
  <button>Do thing with thing id</button>
{{/each}}
...

Your event will then have access to the proper data context for each thing via this:

Template.template1.events({
  'click button'(event, instance) {
    const thingId = this._id;
    // Do something with thingId
  }
});

#3

Another option is to add the id to the button

{{#each thing in things}}
    {{thing.name}}
    <button class="thing" name="doThing" id="{{thing._id}}">Do thing with thing id</button>
{{/each}}

and access the thing-id like so

Template.template1.events({
 'click button.thing': function(event, instance) {
   console.log(event.currentTarget.id);
 }
});

#4

Thanks for responses. Not really a fan of either of these solutions (for the first I’m unhappy about losing the namespacing and the second I’m sometimes trying to encode an object which is a bit of a pain), but I’ll work with it.


#5

Agree with aspin. None of the solutions seem elegant. Is there any real reason why #each in isn’t able to pass its data context into the event?