Generate events from map function

I have a dozen of events like this one inside a Template.instance_name.events() function :

'click .bname1': function(e, i) {
$('.course').show()
$('.course').not('.name1').hide();
 },
'click .bname2': function(e, i) {
$('.course').show()
$('.course').not('.name2').hide();
 }, ...

i wish to use an array of names [‘name1’, ‘name2’, ‘name3’, …] to create events objects

I tried the following, creation an o = {} empty object, and in a map function of my names creating event objects like this:

o['click .' + name] = function (e, i) {
$('.course').show()
$('.course').not('.' + name).hide();
}

But when i pass the o object to my events function it’s not working.

Template.instance_name.events() Expects to get an object with properties and functions. The following worked great for me:

var arr = ['name1', 'name2', 'name3'];
var o = {};
arr.map((name)=>{
  o['click .'+name] = function (e, i) {
    alert(name);
  }
});

Template.instance_name.events(o);

If this is not working either your class names are off or you are not properly getting o into events.

data attribute is more elegant way to implement this.

2 Likes

You were right, the code was ok.
Is it possible that the problem comes from the fact i create the array using a call to the database.
var arr = db.find({}).fetch()
And the events function take the object while it’s still empty… ?

Yes that probably is your issue. You need to call Template.instance_name.events(o); everytime your collection changes. In your case it would look something like this:

Template.insance_name.onCreated(function(){
  this.autorun(function(){
    var arr = db.find({}).fetch();
    var o = {};
    arr.map((name)=>{
       o['click .'+name] = function (e, i) {
          alert(name);
       }
    });

    Template.instance_name.events(o);
  });
});

Indeed if i log the arr i get

main.js:41 []
main.js:41 (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

Isnt it strange that db.find take so much time?
I tried using an async method to await db.fnd({}).fetch() but it doesnt change the behavior.
Is there a way to avoid this problem?

Now the events are loaded, but somehow only once very two times…

@danass there is an example:

<ul>
    <li><a href="https://www.meteor.com/try" data-mykey="1">Do the Tutorial</a></li>
    <li><a href="http://guide.meteor.com" data-mykey="2">Follow the Guide</a></li>
</ul>
  'click a[data-mykey]'(e) {
    e.preventDefault();

    console.log(`clicked on ${e.target.dataset.mykey}`);
  }
1 Like