Importing my methods so that AutoForm can see them - meteor

I don't understand how to import my methods so that AutoForm can see them. Based on the 1.3 best practices, all inserts/updates/deletes should be blocked on the client, and we should use methods instead. These should be imported on a page-by-page basis on the client.
I tried removing the quotes around the meteormethod attribute, and importing the Method in the template's JS file, but this returns an error method.js:11 Uncaught Error: When form type is "method", you must also provide a "meteormethod" attribute.
What's the best practice for this? How do I tell AutoForm where to find my method?

I solved my own problem. Don't import anything, just reference the internal Meteor method name in AutoForm's meteormethod attribute.
For example (if you're using ValidatedMethod):
export const insertProject = new ValidatedMethod({
name: 'projects.insert',
validate: Projects.schema.validator(),
run(fields) {
Projects.insert(fields);
}
});
You'd then use:
{{> quickForm collection=projects id="insertProjectForm" type="method" meteormethod="projects.insert"}}
(note the meteormethod attribute is the same as the name attribute of the ValidatedMethod)
Ref: https://themeteorchef.com/snippets/using-validated-methods/

Related

meteor dynamic template data context

This is a very simple repo, feel free to clone it to test a solution or comment on the commit if its an easy change I'm missing. https://github.com/Falieson/meteor-blaze-examples/commit/8e94f7008cecf647bb23269d9b92cbae49e2398a
I started with meteor create, tested the blaze-components package, and am now figuring out how to use {{> Template.dynamic template=childTemplate data=this }}.
The "hello" counter doesn't pass the value for the reactive variable down to the template, I thought it'd be accessible from {{#with this}} or {{this.count}}
Similarly I would expect the "info" template to render each of the links.
Thank you for your assistance!
It looks at first like there's an error where containerTemplate is receiving counterData as a variable named data but I'm trying to access it using this. When I change containerTemplate.html 's call to render the childTemplate too {{> Template.dynamic template=childTemplate data=data}} the template doesn't render.
All the changes I made in this commit are chasing data context passing for the wrong reasons. I wasn't receiving helper data in the rendered template but I was getting an error in my console that I thought I could ignore because it wasn't causing any issues until trying to use Template.dynamic
modules-runtime.js?hash=8587d18…:231 Uncaught Error: Cannot find module 'meteor/templating'
at makeMissingError (modules-runtime.js?hash=8587d18…:231)
Removing import { Template } from 'meteor/templating'; from my main.js fixed the issue immediately.

Meteor autoform does not wait for element to exist in DOM

I'm adding a rendered template to the document via:
Blaze.renderWithData(Template.page, Session.get(toAdd[i]), document.getElementById('pages'))
This works great... except sometimes with autoform. I'm unsure what's triggering it to happen but some of my autoforms (that can exist inside Template.page, they're added to that template dynamically via the data passed in) show, while other throw a client error:
Uncaught TypeError: Cannot read property 'formValues' of undefined :: autoform-inputs.js:162
markChanged :: autoform-inputs.js:169
updateTrackedFieldValue :: afFieldInput.js:72
There's a timeout set to 0 in that afFieldInput.js on line 71. Upping this to 500 fixes the error above but is hacky and causes other issues.
The best I can surmise, autoform is attempting to get the form from the DOM by id before it exists in the DOM, probably it exists as a document fragment via Blaze, if I had to guess.
I can confirm that AutoForm.templateInstanceForForm is getting the correct form ID, but that document.getElementById(formId) is returning null.
The other possibility is that Blaze is, for some reason, failing to render the template but not warning me.
I was WAY off.
I had changed the schema, but was trying to open a doc with improper data for the new schema. Going to post this answer in case someone comes across the same error.
Also, don't pass in objects or functions all the way to the template that autoform doesn't expect, apparently. You can access them still, but remove them from the attr object by declaring attr as a function in the helper, returning this.attr sans any objects that don't need to be sent on to the template.

meteor iron-router and getting the names of all routes for the accounts-entry package

The popular accounts-entry package has an iron-router related bug in it. I believe the later versions of iron-router changed to work better as middleware and so a call to Router.routes
At line 87 of this file the following code is used:
_.each Router.routes, (route)->
exclusions.push route.name
# Change the fromWhere session variable when you leave a path
Router.onStop ->
# If the route is an entry route, no need to save it
if (!_.contains(exclusions, Router.current().route?.getName()))
Session.set('fromWhere', Router.current().path)
Unfortunately it does not seems like doing an _.each on Router.routes is a solution that works anymore because Router.routes does not return and object with .name properties in it.
How would you get the name of all the routes with the latest iron-router?
This one is a little tricky : in the latest version of iron:router, Router.routes is now defined as an array of functions.
Thing is, functions already have a default name property in JS which contains the name the function was assigned on definition.
var myFunc = function funcName(){...};
console.log(myFunc.name); // == "funcName"
Fortunately, there is a getName method defined on the route items of the array and you can use this piece of code to iterate over all routes and get their name :
_.each(Router.routes, function(route){
console.log(route.getName());
});

Get data from the parent scope

Im trying to implement a single-page app with Ractive using components, and I need to have some page-wide options. I did like this:
...
data: {
options: {
someOption: true
},
...
Everything was fine while I used it like {{#if options.someOption}}, but then I faced a problem - rective.get('options.someOption') returns undefined (both with ractive.get('options')). Observing dont work as well. Is there any way to make my code understand me?
UPD. Accidentally solved problem with a portion of magic - get() starts working when I place {{options.someOption}} on template.
Ractive programmatic data access within an instance (includes components) can currently only "see" data that is:
Defined as data
Specified explicitly as a component parameter
Used as a reference in the template
For #1, you can include the options as default data and it will be available to all instances:
Ractive.default.data = {
options: {...}
}
Any new Ractive instance, including components, will have an options data property.
For #2, even if you have deeply nested components, you can have the parent of the component that needs the data include it as a parameter:
// Component somewhere in the "app" hierarchy.
// By referencing {{options}} in its template, it will find that data
// make it explicit on the widget component, which can then use it
// programmatically
<widget options='{{options}}'/>
For #3, you can include a "dummy" reference in the component template:
// by using it in the template, it is now available for programatic access
{{#with options}}{{/with}}
Of course then there's #4, enhancing Ractive to allow same lookup in code as template

How to pass an object from to a block helper back to the block in meteor blaze?

Before Meteor 0.8, that brought blaze, I was able to pass objects to a custom block helper content like this:
return options.fn(object)
Now that with blaze, block helpers require to return a template something like this.
return Template.someTemplate
How can I achieve the old behaviour. What I want to to is the following:
I use a blockhelper
{{#blockhelper argument="something"}}
{{somePartOfTheObject}}
{{/blockhelper}}
Then in the the blockhelper definition, I want to do some stuff based on the argument, that will return an object.
UI.registerhelper "blockhelper", () ->
object = getStuffFrom(this.argument)
return Template.someTemplate(object)
As needed by blaze I created a minimal template
<template name="someTemplate">
{{> UI.contentBlock}}
</template>
Now blaze does not allow to pass an object to this template, so it can be used within the block contents.
How can I get around this?
I know the meteor-way would be to get the object in the controller. But as I want to use this for a prototyping framework, I want to be able to create said object or objects directly from the blockhelper, so someone can pass argmuents that will get converted to objects.
The solution turns out to really simple.
If I have a helper:
UI.registerhelper "blockhelper", () ->
object = getStuffFrom(this.argument)
return Template.someTemplate
The variables and object of the helper are actually available in the template. So you simply do:
<template name="someTemplate">
{{> UI.contentBlock object}}
</template>

Resources