Accessing template.instance from autoform onSuccess callback


#1

I have a reactive dictionary in my template instance.

Template.newMessage.onCreated(function () {
    ...
    this._msg = new ReactiveDict();
    ...
});

And I’m using autoform to hit a server method:

+quickForm id='linkPatient' schema='Schema.LinkPatient' type='method' meteormethod='linkPatient' data-msg=_msg

Then I hook onto the result of the form to do two things, 1. get a pass/fail from the server(note, fail != error), 2. update the reactive dict’s state.

AutoForm.hooks({
    linkPatient: {
        before: {
             // accessing template data (via form attribute) on the way to the server
             insert.oid = this.formAttributes['data-msg'].get('organisationId');
            }
        },
        onError: function (type, err) {
            ...
        },
        onSuccess: function (type, res) {
            if (res)
                // setting the template state on the callback, HOLY COW!
                this.template.view.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView.parentView._msg.set(...)
            else
               // show failed message
        }
    }
});

This is how I arrived at my solution

Any other ways?

Second question: How do I access template instance from simpleschema? Say I wanted to filter a list of options defined in the schema based on a template state for that particular instance.

In both cases, am I repeatedly looking up the template ladder until I get to my parent template?


#2

Perhaps https://atmospherejs.com/aldeed/template-extension can give you better ideas about achieving the same thing without ...parentView.parentView.parentView.parentView...


#3

I’ve had a read through it and there are two relevant functions:

use template.parent(numLevels, includeBlockHelpers) to access a parent template instance.

This is absolutely horrible, putting in arbitrary random numbers to go back template levels shudders, yuck!

use template.get(fieldName) to access the first field named fieldName in the current or ancestor template instances.

This is better in that it will find a template instance with the right field name. I was actually thinking along the same lines but it really just feels like a massive hack! and i’d have to name the field with a fairly unique name to avoid false positives… just feels like it’s a lot harder than it should be. hooks should just have the template.instance state imo, not it’s inner implementation of nested template.instance

Also, this doesn’t solve simpleschema’s options field. That doesn’t even have any state (in chrome debugger). Just feeling like i’m bang my head on a brick wall… I mean I’m pretty thick headed.

I’m leaning towards Session or minimongo (state as part of collection), constant micro updates, F5-proof. Give.


#4

Well, you could go with a reactive dict that is created on meteor startup (rather than template oncreated) so that it basically acts like a dedicated session.


#5

I’m trying to avoid using Session or global dicts. Atm the dict gets pulled down onDestroy and two instances of the template would still work. That’s what I like about doing it this way.

However, it seems I need a custom solution for every package that deals with templating (e.g autoforms use extension, simpleschema functions, use sessions, my own nested templates, pass parent state into child, collection helpers, … haven’t needed to pass state into them yet).

I’m looking for a standard way where i can specify the template.instance so I can use the template state in a consistent way for all functionality that executes in a template. I don’t even mind using globals, but the problem is, alot of these functions dont even know which template they are being called from! e.g the onSuccess hook, schema’s options function…


#6
  1. You can monkeypatch the templateInstance prototype as suggested in
  1. Or you could try a top->down approach.

Take the reactive dict from the parent template and set it on the data context of the child template.

  1. Finally, this thread has lots of valuable information: