Upsert in Autoform?

I am repeating something similar to the code below in my app several times for various schemas and collections, so it’s violating the DRY principle. Is there a better way to do upsert in Autoform?

    {{#if merchant}}
        {{#autoForm collection="Merchants" id="merchantForm" type="update" doc=merchant}}
            {{> merchantFields }}
        {{/autoForm}}

    {{else}}
        {{#autoForm collection="Merchants" id="merchantForm" type="insert"}}
            {{> merchantFields }}
        {{/autoForm}}
    {{/if}}

Could you create a template to do this for you?

<template name="upsertForm">
    {{#if doc}}
        {{#autoForm collection=collection id=id type="update" doc=doc}}
            {{> Template.contentBlock}}
        {{/autoForm}}

    {{else}}
        {{#autoForm collection=collection id=_id type="insert"}}
            {{> Template.contentBlock}}
        {{/autoForm}}
    {{/if}}
</template>

Then use it:

{{#upsertForm doc=merchant collection="Merchants" id="merchantForm"}}
  {{> merchantFields }}
{{/upsertForm}}

Seems like this doesn’t really need to be a feature in AutoForm if you could just do the above.

2 Likes

Thank you for the code snippet. I was just wondering whether I am doing the right thing - surely I am not the only one who needs to upsert? Seems like a common scenario.

2 Likes

Fair enough. This could be a good feature; I think forms in Rails work like this by default.

1 Like

I think this discusses a similar concept:

  • Change the type attribute’s value to “insert” or “update” as appropriate, probably by updating a reactive variable.
  • Change the doc attribute’s value to the correct document for an update or to null (or a document containing default values) for an insert, probably by updating a reactive variable.
  • Call AutoForm.resetForm(formId). This will clear any existing validation errors for the form.

The doc=merchant in this case, how do I pass it? From iron-router, using this as the doc is fine, but how else can I get it into my template.

I’ve tried this:

Template.notePad.helpers({
    note: function() {
        return Note.findOne({
            userId: Meteor.userId()
        });
    }
});

and this is the form

<template name="notePad">
{{#if note}}
{{> notePadEdit}}
{{else}}
{{> notePadAdd}}
{{/if}}

</template>
<template name="notePadAdd">
{{#autoForm collection="Note" id="notePadAdd" type="insert"}}
{{> afQuickField name='text' rows=6}}
<button class="btn-floating waves-effect waves-light"><i class="material-icons">save</i></button>
{{/autoForm}}
</template>

<template name="notePadEdit">
{{#autoForm collection="Note" id="notePadEdit" doc=note type="update" autosave=true}}
{{> afQuickField name='text' rows=6}}
{{/autoForm}}
</template>

thanks

1 Like

For anyone else wondering how to do this, here is the current best practice using AutoForm to use the same form for insert and update.

First, add your form and set the doc and type as helper variables that you can manipulate.

{{> quickForm collection="Schedules" id="scheduleForm" doc=currentSchedule type=formType}}

Set your formType as either a reactive-var (better) or Session variable with a default value of “insert”

Template.schedule.onCreated(function(){
    this.formType = new ReactiveVar( 'insert' );
});

Next, set up helpers for both the current doc and formType. This checks for a current document, and if it exists, updates the form to an “update” type and provides the document to update. The formType helper just fetches the current formType value.

Template.schedule.helpers({

	currentSchedule: function() {
		var currentSchedule = Schedules.findOne({ campaignId: FlowRouter.getParam('campaignId') });
		if (currentSchedule) {
			Template.instance().formType.set('update');
			return currentSchedule;
		}
	},

	formType: function() {
		var formType = Template.instance().formType.get();
		return formType;
	}

});
5 Likes

For me, the suggestion of @jamielob works great :slight_smile:

Does anyone know why it’s not necessary to do AutoForm.resetForm in opposition to what’s suggested in docs? -> https://github.com/aldeed/meteor-autoform#can-i-reuse-the-same-quickform-or-autoform-for-both-inserts-and-updates

2 Likes