How to generically run multiple autoruns? (in Meteor or Blaze Components)


#1

Hi guys,

within “Blaze Components” or within Meteor in general:

How do I generically run multiple autoruns?
Is this possible at all, or do I have to hardcore?

@mitar: Do you have an idea how to do this?

For example:

// Let's link some "aldeed:Autoform-fields" with an ReactiveDict
ExampleComponent extends BlazeComponent {
  onCreated() {
    var fieldNamesArray = ['name', 'surename', 'country'];
    this.filterDict = new ReactiveDict('filter');

    fieldNamesArray.forEach(function(element, index) {
      // Generic Autorun (this THROWS an ERROR right now)
      this.autorun(this.filterDict.set(element, AutoForm.getFieldValue(element, 'formId')));
    });
  }
}

#2
onCreated() {
  self = this;

self.autorun(self.filterDict.set(element, AutoForm.getFieldValue(element, 'formId')));

#3

@shock: Yeah this works! Thanks a lot for pointing this out! :smiley:

But I actually stumbled upon another problem: Is it possible to use autorun within a mixin’s.onCreated?

This code is giving me problems:
Is it because the mixin does not have its own template?
Is there a way to make this work within the mixin?


class MixinComponent extends BlazeComponent {
  onCreated() {
    var self = this;
    // THIS THROWS ERROR "Uncaught Error: The component has to be created before calling 'autorun'"
    self.autorun(function() {console.log('autorun MixinComponent')});
  }
}

class ExampleComponent extends BlazeComponent {
  mixins() {
    return [MixinComponent];
  }

  template() {
    return 'ExampleComponent';
  }

  onCreated() {
    var self = this;

    self.autorun(function() {console.log('autorun ExampleComponent')});
  }

}
ExampleComponent.register('ExampleComponent');

#4

Ahhh… I think I got it: seems like self.mixinParent().autorun(function() {console.log('autorun MixinComponent')}); does the job! :smile:


#5

alternative, you could use a ES6 fat arrow here, as it presents a lexical this

fieldNamesArray.forEach((element, index) => {
      this.autorun(this.filterDict.set(element, AutoForm.getFieldValue(element, 'formId')));
    });

#6

In my apps I have my own base classes for mixins, so that it is simpler to use them:

Also, for your case I would simple use computed field API.


#7

@mitar: Thanks a lot for your response! So far a really really love your “Blaze Components”! It helps SO MUCH to structure my project!! :smiley: BIG THUMBS UP!!! :love_letter:

Does the “computed field” package allow me to a single instance as a dictionary?
I need to be able to use it like this:


#8

Thats a great idea! You should put that into the docs and make it part of the framework. :smile:


#9

Why you need filterDict and would not just have a set of fields instead?


#10

I want to keep core minimal. But there is already a ticket to publish examples of such base classes and mixins: https://github.com/peerlibrary/meteor-blaze-components/issues/86

But yes, the recommended way is to create your own base class and then use that in your components. And then you can add any common stuff there. Both for components and mixins.