5

Is there a prescribed way to create a custom validator in loopback? As an example, assume that I want to create something like:

Validatable.validatesRange('aProperty', {min: 0, max: 1000})

Please note that I am aware of:

Validatable.validates(propertyName, validFn, options)

The problem I have with validates() is that validFn does not have access to the options. So, I'm forced to hard code this logic; and create a custom method for every property that needs this type of validation. This is undesirable.

Similarly, I am familiar with:

Model.observes('before save', hookFn)

Unfortunately, I see no way to even declare options for the hookFn(). I don't have this specific need (at least, not yet). It was just an avenue I explored as a possible alternative to solve my problem.

Any advice is appreciated. Thanks in advance!

Cliff Chaney
  • 414
  • 5
  • 13

2 Answers2

18

There is a mention of how to do this over at https://docs.strongloop.com/display/public/LB/Validating+model+data

You can also call validate() or validateAsync() with custom validation functions.

That leads you to this page https://apidocs.strongloop.com/loopback-datasource-juggler/#validatable-validate

Which provides an example.

I tried it out on my own ...

  Question.validate('points', customValidator, {message: 'Negative Points'});
  function customValidator(err) {
    if (this.points <0) err();
  }

And since that function name isn't really used anywhere else and (in this case) the function is short, I also tried it out with anonymous function:

Question.validate('points', 
        function (err) { if (this.points <0) err(); }, 
        {message: 'Question has a negative value'})

When points are less than zero, it throws the validation error shown below.

{
  "error": {
    "name": "ValidationError",
    "status": 422,
    "message": "The `Question` instance is not valid. Details: `points` Negative Points (value: -100).",
    "statusCode": 422,
    "details": {
      "context": "Question",
      "codes": {
        "points": [
          "custom"
        ]
      },
      "messages": {
        "points": [
          "Negative Points"
        ]
      }
Un3qual
  • 1,332
  • 15
  • 27
Dakotah North
  • 1,324
  • 12
  • 29
  • Thank you for your answer. I've marked it since this is the approach I've had to use. But you seem to be missing the point of my original question. The problem with this approach is that it forces you to hard code logic into the validator that eliminates its reusability. What if, in the next app or somewhere else on the form your minimum is 5? You need another function. I'm just a dreamer/purest. But notice how you pass an options object into validate()? Ideally, I'd have access to that object in the function. That would solve my problem! – Cliff Chaney Sep 13 '16 at 12:22
0

What you are looking for is validatesLengthOf(). For example:

Validatable.validatesLengthOf('aProperty', {min: 0, max: 1000});

Here is the documentation links: All the methods of Validatable class and Model-wise validation.

xangy
  • 1,185
  • 1
  • 8
  • 19
  • Thank you for your reply. Unfortunately, that is NOT what I need. For one, I used an EXAMPLE of ValidatesRange() - which is intended to validate the minimum and maximum range of values, not a range of valid lengths. However, please note that I'm not looking for that specific validation either! What I would like is a way to be able to define my own validations - LIKE a ValidatesRange(). The documented ways that I have found to do this are all crippled (from what I can tell). Please see my original post. – Cliff Chaney Sep 21 '15 at 15:30
  • Have you considered using [prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype) on your model? – xangy Sep 28 '15 at 14:03
  • Not really. It's an example of what I'd like to do though. That function is validating the LENGTH of something. What if I want to validate the range of values (like an int that can be between 1 and 100)? But even this is just representative. The point is, validatesLengthOf() obviously gains access to the options object. I'd like to write a Validatable function that does the same (i.e. can access the options object). Thank you for your answer. – Cliff Chaney Sep 13 '16 at 12:25