Can I define a custom validation with options for Loopback?
Asked Answered
P

2

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!

Preliminaries answered 17/9, 2015 at 13:38 Comment(1)
I can offer no help here, other than to agree that this is extremely frustrating!Fractionize
K
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"
        ]
      }
Kamerad answered 27/12, 2015 at 17:38 Comment(1)
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!Preliminaries
T
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.

Tourbillion answered 18/9, 2015 at 14:24 Comment(3)
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.Preliminaries
Have you considered using prototype on your model?Tourbillion
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.Preliminaries

© 2022 - 2024 — McMap. All rights reserved.