javascriptmeteorecmascript-6synchronousmeteor-autoform

Call Meteor.call() and wait inside `before: insert` hook


Scenario:

I am trying to insert an Appointment for a client using autoform only when the dates do not clash. below is the code to get brief Idea.

{{#autoForm id='insertAppointmentForm' collection=appointment type="insert" 
              doc=this validation="browser"}}
    <fieldset>
      <!-- All fields here -->
    </fieldset>
    <button type="submit" class="btnn"> Create </button>
{{/autoForm}} 

I am adding hook to above autoform insert code as below,

var hooksObject = {
  before: {
    insert: function(doc) {
      console.log(doc);
      Meteor.call('checkAppointmentClash', doc, function(error, response){
          if(error){ } else { }
      });
      return doc; // I want to wait here 
    }
  },
  onSuccess: function(formType, result) {},
  onError: function(formType, error) {}
};

AutoForm.addHooks(['insertAppointmentForm'], hooksObject, true);

Problem:

The issue here is that form gets submitted even if error returned from Meteor.call() and inserts the document to database. I know that the Meteor.call() is asynchronous call, but how can I wait for the result? only then I want to proceed with submit if no error.


Solution

  • Hooks can work asynchronously. From the documentation:

    These functions can perform asynchronous tasks if necessary. If asynchronicity is not needed, simply return the document or modifier, or return false to cancel submission. If you don't return anything, then you must call this.result() eventually and pass it either the document or modifier, or false to cancel submission.

    So the code could look like this:

    insert: function(doc) {
      // note using () => {} to bind `this` context
      Meteor.call('checkAppointmentClash', doc, (error, response) => {
        if(error) {
          this.result(false);
        } else {
          this.result(doc);
        }
      });
      // return nothing
    }
    

    Although, I'd suggest you to rethink your flow. It's wrong to check for "clash" in a hook. You should be doing that on "user entered data" step and disable/enable "Submit" button accordingly.