How can I validate with Collection2 on the client side?


#1

I always use methods to insert, update and remove. This is the way my code look just now:

Client side

Template.createClient.events({
  'submit form': function(event, tmpl) {
    e.preventDefault();
    var client = {
      name: event.target.name.value,
      // .... more fields
    }

    var validatedData = Clients.validate(client);
    if (validatedData.errors) {
      // Display validation errors
      return;
    }

    Meteor.call('createClient', validatedData.client, function(error) {
      if (error)
        // Display error
    });
  }
});

Client and server side:

Clients = new Mongo.Collection("clients");

Clients.validate = function(client) {
  // ---- Clean data ----
  client.name = _.str.trim(client.name);
  // .... more fields clean

  // ---- Validate data ---
  var errors = [];
  if (!client.name)
    errors.push("The name is required.");
  // .... more fields validation

  // Return and object with errors and cleaned data
  return { errors: _.isEmpty(errors) ? undefined : errors, client: client };
}

Meteor.methods({
  'createClient': function (client) {
    // --- Validate user permisions ---

    // If server, validate data again
    if (Meteor.isServer) {
      var validatedData = Clients.validate(client);
      if (validatedData.errors)
        // There is no need to send a detailed error, because data was validated on client before
        throw new Meteor.Error(500, "Invalid client."); 
      client = validatedData.client;
    }

    check(client, {
      name: String,
      // .... more fields
    });

    return Clients.insert(client);
  }
});

Meteor.call is executed on client and server side, but Meteor doesn’t have a way stop the running on the server side if the validation on the client side fails (or at least, I don’t know how). With this pattern, I avoid sending data to the server with Meteor.call if validation fail.

I want to start using Collection2, but I can’t figure how to get the same pattern. All the examples I found involve the usage of direct Insert and Update on client side and Allow/Deny to manage security, but I want to stick with Meteor.call.

I found on documentation that I can validate before insert or update, but I don’t know how to get this to work:

Books.simpleSchema().namedContext().validate({title: "Ulysses", author: "James Joyce"}, {modifier: false});

I know the autoform package, but I want to avoid that package for now.

How can I validate with Collection2 on the client side before sending data to the server side with Meteor.call? Is my pattern wrong or incompatible with Collection2 and I need to do it in another way?


#2

I think the way to go, in your case, is to manually validate with SimpleSchema. The doc is here.


#3

This is pretty straight forward if you’re using collection2 / simple-schema, check out the docs again and I found a good starting tutorial, here I’ve landed up extending this quite a bit can pop what I’ve been doing onto GitHub if you like.