Separate form validation with Meteor
Asked Answered
D

4

11

I'm using collection2 and I'm trying to get it to handle validation is a specific way. I have a profile schema which looks kind of like this:

Schema.UserProfile = new SimpleSchema({
    name: {
        type: String,
        optional: false
    }
    location: {
        type: String,
        optional: true
    }
    gender: {
        type: String,
        optional: false
    }
});

Schema.User = new SimpleSchema({
    username: {
        type: String,
        optional: true
    },
    emails: {
        type: Array,
        optional: true
    },
    "emails.$": {
        type: Object
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true
    },
    roles: {
        type: [String],
        optional: true
    },
    heartbeat: {
        type: Date,
        optional: true
    }
});

Meteor.users.attachSchema(Schema.User);

Now, on my registration form I'm requiring the user to select their gender and then later once they log in, users are presented with a separate form asking for their name and location. Here's the problem:

The registration form works and everything goes through with saving. When they try to save the internal form with location and name though I get an error:

Error invoking Method 'updateProfile': Gender is required [400]

I know it's happening because it's required in the schema but I've already obtained this information. How do I not require that? Or do I set up validation per form?

Droplight answered 24/1, 2016 at 14:56 Comment(2)
What kind of additional detail are you looking for?Estellaestelle
I'm just looking for a little more feedback and a more elegant solution.Droplight
E
3

From the SimpleSchema docs:

Say you have a required key "friends.address.city" but "friends.address" is optional. If "friends.address" is set in the object you're validating, but "friends.address.city" is not, there is a validation error. However, if "friends.address" is not set, then there is no validation error for "friends.address.city" because the object it belongs to is not present.

So the error happens because you're including profile on both forms and gender is not optional within profile. I can think of two ways to solve this:

  1. Have additional objects under profile that are both optional and contain required fields for name/location on one (though it seems like location might be optional in both scenarios based on your code) and a required field for gender on the other. I don't particularly like this solution but it prevents needing form validation.

  2. Use jQuery form validation (I use the package themeteorchef:jquery-validation) and make all your fields in profile optional.

  3. It also looks like SimpleSchema accepts a function for the optional property, so you could use some custom logic there - maybe you get arguments or a context in that function that will allow you to do what you want?

Hope that helps!

Estellaestelle answered 26/1, 2016 at 1:41 Comment(0)
V
3

You have to add validation through jquery or you can use toaster for display the error on client side. Read this also : link

Violist answered 27/1, 2016 at 9:59 Comment(0)
O
3

I assume you use aldeed:autoform for your forms. When you use normal type in the form, all fields, even those already filled marked as mandatory have to be submitted. Two ways to fix this:

  • Dirty way: set hidden field with the prefilled value.
  • You can also set your form type as update as seen in the doc. This way, simple-schema will validate your newDoc already filled with your previous entries without screaming.

The solution number two is the one I use in most cases. This plus autoform's hooks give you enough flexibility to adapt to most use-cases you might encounter.

Otho answered 1/2, 2016 at 18:2 Comment(0)
P
3

I don't know whether or not it is a more elegant solution, but we've stopped attaching simpleSchemas to documents in our current project.

We instead have different schemas in each collection's namespace, one for checking user input on insert, one on update, and and one to be used to fill defaultValue when inserting a new doc (which can be done either by the client or the server, in which case we don't check for input). We call .validate() or .clean() depending on what we want to do.

With clever use of the possibility to build schemas from array of schemas, we're not writing bigger schemas in the end (there's more of them though), but we have total control on when we check, and which fields are checked.

Projector answered 10/2, 2016 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.