Let's imagine a complex form component such as a map that lets you select a location stored as a { lat, lng } pair. Currently we can do input: Map which activates the correct form input component.
But the component won't be functional unless we also specify the correct type (a SimpleSchema object with lat and lng subfields), GraphQL type (including input types), and maybe even validation (lat and lng have to be floats contained between x and y).
Currently all this has to be done manually, but we could automate it via a pattern I'm calling "field type templates" until I find a better name (field factories? field models?):
The makeMap template function would take a field name, field schema, and some options, and return a new schema that includes all the elements mentioned above. That field schema is then included in the collection schema as before.
Here's a real-world example for a future Likert Scale component:
import { addGraphQLSchema } from 'meteor/vulcan:core';
import SimpleSchema from 'simpl-schema';
export const makeLikert = (fieldName, field) => {
// get typeName from fieldName unless it's already specified in field object
const { typeName = `${fieldName}Type` } = field;
if (!field.options) {
throw new Error(`Likert fields need an 'options' property`);
}
// build SimpleSchema type object for validation
const typeObject = {};
field.options.forEach(({ value }) => {
typeObject[value] = {
type: SimpleSchema.Integer,
};
});
// create GraphQL types for main type, create input type, and update input type
addGraphQLSchema(`type ${typeName} {
${field.options.map(({ value }) => `${value}: Int`).join('\n ')}
}
input Create${typeName}DataInput {
${field.options.map(({ value }) => `${value}: Int`).join('\n ')}
}
input Update${typeName}DataInput {
${field.options.map(({ value }) => `${value}: Int`).join('\n ')}
}
`);
// add additional field object properties
const likertField = {
...field,
type: new SimpleSchema(typeObject),
input: 'likert',
typeName,
};
return likertField;
};
Let's imagine a complex form component such as a map that lets you select a location stored as a
{ lat, lng }
pair. Currently we can doinput: Map
which activates the correct form input component.But the component won't be functional unless we also specify the correct type (a SimpleSchema object with
lat
andlng
subfields), GraphQL type (including input types), and maybe even validation (lat
andlng
have to be floats contained between x and y).Currently all this has to be done manually, but we could automate it via a pattern I'm calling "field type templates" until I find a better name (field factories? field models?):
The
makeMap
template function would take a field name, field schema, and some options, and return a new schema that includes all the elements mentioned above. That field schema is then included in the collection schema as before.Here's a real-world example for a future Likert Scale component: