lukejagodzinski / meteor-astronomy-validators

https://atmospherejs.com/jagi/astronomy-validators
MIT License
11 stars 13 forks source link

[1.0.0 RC 2] TypeError: Object #<Object> has no method 'each' #27

Closed laurentpayot closed 8 years ago

laurentpayot commented 8 years ago

With the new 1.0.0 RC 2 version of validators (didn't test with RC 1), along with astronomy 1.0.0 RC 3, I'm using the following code (V = Validators):

    'languages': {
      type: 'array',
      "default": function() {
        return [];
      },
      nested: 'string',
      validators: [V.array(), V.maxLength(100)],
      validator: V.each(V.and(V.length(2)))
    }

With or without the validators line (it is unclear if we can use both validators and validator), I get the Meteor error TypeError: Object # has no method 'each'

laurentpayot commented 8 years ago

Same with astronomy@1.0.0-rc.4.

lukejagodzinski commented 8 years ago

I've updated documentation to state it clearly. In the field's definition you use singular form validator:

fields: {
  languages: {
    /* ... */
    validator: V.each()
  }
}

However in the class definition you use validators because you define validators for many fields:

Item = Astro.Class({
  name: 'Item',
  /* ... */
  validators: {
    languages: V.each()
  }
});
laurentpayot commented 8 years ago

After reading the new docs it is still a bit confusing... Could you please complete the following example with all the validation lines needed to ensure languages is an array of strings with at most 100 elements, and that every strings in this array are 2 characters long? That would really makes things clearer, thanks in advance...

Item = Astro.Class({
  name: 'Item',
  /* ... */
  fields: {
    languages: {
      type: 'array',
      nested: 'string'
    }
  }
});
lukejagodzinski commented 8 years ago
Item = Astro.Class({
  name: 'Item',
  /* ... */
  fields: {
    'languages': {
      type: 'array',
      nested: 'string',
      default: function() {
        return [];
      },
      validator: [
        // The array can have up to 100 elements
        Validators.maxLength(100),
        // Now every element of array has to...
        Validators.every(
          Validators.and([
            // ... be a string and...
            Validators.string(),
            // ... has to be exactly 2 characters long
            Validators.length(2)
          ])
        )
      ]
    }
  }
});

I will add this example to the documentation because in deed it may be difficult at the beginning.

UPDATE: I've fixed example. There was an error. you have to pass validator to the every validator not array of validators.

laurentpayot commented 8 years ago

Thanks @jagi, I was getting crazy with weird errors before you updated the example above ;) I can finally validate my arrays of strings :+1:

However I need to generate custom error messages (i18n), how can we tell wich one of minLength validator triggered an error in the following example? (e.data.fieldValue is the array in both cases)

    'names': {
      index: true,
      type: 'array',
      nested: 'string',
      validator: [V.required(), V.array(), V.minLength(1), V.every(V.and([V.minLength(2), V.maxLength(201)]))]
    },
lukejagodzinski commented 8 years ago

Hmm right now it's not possible to tell which value caused error. I will try fixing it. Will let you know if I figured something out.

laurentpayot commented 8 years ago

Ok, for now I'll try to find a workaround.

lukejagodzinski commented 8 years ago

Ok I've managed to fix it. It will appear in the next RC version.

laurentpayot commented 8 years ago

:+1: